рисование в MSE

Вопросы программирования и использования MSEide + MSEgui.

Модератор: Модераторы

Аватара пользователя
Attid
долгожитель
Сообщения: 2589
Зарегистрирован: 27.10.2006 17:29:15
Откуда: 44°32′23.63″N 41°2′25.2″E
Контактная информация:

рисование в MSE

Сообщение Attid »

как тут все необычно делается это не описать словами =)
чтобы добраться до Canvas нужно обрабатывать событие =/

ну да ладо это дело привычки а вот как бороться с такими вещами:

Код: Выделить всё

  with Canvas do
  begin
    Font.Size := 4;
    Pen.Color := clBlack;
    Brush.Color := clWhite;
    TextOut(FLeft, FTop, FText);         
    TextOut(FLeft, FTop+14, GetTypText);
  end;

MSE не понимает тут каждую строчку =(

так же не понял где задать толщину

Код: Выделить всё

Canvas.Pen.Width 
Аватара пользователя
debi12345
долгожитель
Сообщения: 5761
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Сообщение debi12345 »

Attid писал(а):как тут все необычно делается это не описать словами =)
чтобы добраться до Canvas нужно обрабатывать событие =/

Запрошено в "Published" - для преднастроек.

Attid писал(а):так же не понял где задать толщину

Код: Выделить всё

Canvas.Pen.Width 



/

Код: Выделить всё

/
// Рисование графика СИНУС на tpaintbox-t
//
procedure tmainfo.paint(const sender: twidget; const canvas: tcanvas);
var
 hstep: extended;
 yaxis: integer;
 i: integer;
 lastpoint, nextpoint: pointty;
begin
 with canvas do begin
  hstep:= clipbox.cx/360;
  yaxis:= clipbox.y + clipbox.cy div 2;
  linewidthmm:= 1.0;

  lastpoint:= makepoint(0,yaxis);

  for i:= 0 to 360 do begin

   nextpoint:= makepoint(
    round(i*hstep),
    round(yaxis+sin(degtorad(i))*(clipbox.cy/2))
   );   

   linewidthmm:= 0.5;
   drawline(
    makepoint(lastpoint.x,yaxis),
    makepoint(nextpoint.x,yaxis),
    cl_red
   );

   linewidthmm:= 1.0;   
   drawline(lastpoint,nextpoint,cl_blue);
   lastpoint:= nextpoint;

  end;

 end;
end;

------

Антиалиасной отрисовки линий нет. Это задача специализированных графических библиотек.
Аватара пользователя
debi12345
долгожитель
Сообщения: 5761
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Сообщение debi12345 »

По поводу "где холст ?"...

Ответ:

Виджеты не имеют холста. Тот холст, что используется для отрисовки - как правило холст окна, но может быть также холстом битмапа, принтера, или...
MSEgui использует один и тот же холст для отрисовки окна целиком со всеми его виджетами.
Аватара пользователя
Attid
долгожитель
Сообщения: 2589
Зарегистрирован: 27.10.2006 17:29:15
Откуда: 44°32′23.63″N 41°2′25.2″E
Контактная информация:

Сообщение Attid »

вопрос где текст ? =(

единственно ечто нашел это
procedure internaldrawtext(); virtual;

или выход только распологать лабел поверх?

пока отмена кажется нашел =)
Аватара пользователя
Attid
долгожитель
Сообщения: 2589
Зарегистрирован: 27.10.2006 17:29:15
Откуда: 44°32′23.63″N 41°2′25.2″E
Контактная информация:

Сообщение Attid »

лучше бы не нашел =)

procedure drawtext(
const canvas: tcanvas;
const text: msestring;
const dest: rectty;
flags: textflagsty = [];
font: tfont = nil;
tabulators: tcustomtabulators = nil
); overload;

только я вот не понял это мне надо просчитать сколько места займет текст ?
в лазаре TextOut задается только точка откуда надо начать писать текст а тут он будет вписываться в тот квадрат который ему выдашь ? пойду проверю =)
Аватара пользователя
Attid
долгожитель
Сообщения: 2589
Зарегистрирован: 27.10.2006 17:29:15
Откуда: 44°32′23.63″N 41°2′25.2″E
Контактная информация:

Сообщение Attid »

ой а там все прекрасно в rectty можно указывать только x,y
а cx cy равен 0

вот только проблема с определением textwidth как его узнать =/
нужно для размещения текста посередине картинки
Аватара пользователя
debi12345
долгожитель
Сообщения: 5761
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Сообщение debi12345 »

вот только проблема с определением textwidth как его узнать =/
нужно для размещения текста посередине картинки

Навскидку :
1) msegraphics.pas : tcanvas.getstringwidth(string,font);

Помните - в MSE* GUI-элементы не имеют своих canvas, а используют единый общий ! Поэтому многие методы около-рисования реализованы в виде глобальных процедур, принимающих модификаторы (цвет, шрифт,...) - чтобы по ходу автоматически сохранять/восстанавливать общий canvas.

Чего пока нет (и нужно будет разве что в навороченных текстовых редакторах ) - держать ( и рисовать ) в одной richstring-строке текст разными шрифтами. Сейчас для этих целей нужно держать массив richstring-ов. Мартин говорит, что невозможно хранить в строке данные сразу о нескольких шрифтах (и стилях,размерах,..) - без жуткой потери производительности. Вопрос обсуждался, лобовое решение не найдено. Если кому-то эта тема интересна - милости просим. Тут главное - идея "как?".


===
Мартин о рисовании (вчера):

Я увидел рисовальный пример на "frepascal.ru".
В MSEgui есть два метода рисования текста :
- простое позиционирование по базовой линии первого символа - с использованием tcanvas.drawstring ( с автопереводом строки на lineheight )
- использование процедур "drawtext" модуля "msedrawstring.pas".

Попозже, будет возможно задать подгонку текста в по размеру прям-ка рисования, используя флаги и табуляторы

( от меня : думаю - как в репортере, "Latter" - обычно это несколько дней. )

Оптимизированное рисование из примера:


Код: Выделить всё

unit main;
{$ifdef FPC}{$mode objfpc}{$h+}{$INTERFACES CORBA}{$endif}
interface
uses
 msegui,mseclasses,mseforms,msesimplewidgets,msegraphics,msegraphutils;

type
 tmainfo = class(tmseform)
   tpaintbox1: tpaintbox;
   procedure paint(const sender: twidget; const canvas: tcanvas);
   procedure paint1(const sender: twidget; const canvas: tcanvas);
   procedure paint2(const sender: twidget; const canvas: tcanvas);
 end;
var
 mainfo: tmainfo;
implementation
uses
 main_mfm,math;
 
procedure tmainfo.paint(const sender: twidget; const canvas: tcanvas);
var
 hstep: extended;
 yaxis: integer;
 i: integer;
 lastpoint, nextpoint: pointty;
begin
 with canvas do begin
  hstep:= clipbox.cx/360;
  yaxis:= clipbox.y + clipbox.cy div 2;
  linewidthmm:= 1.0;

  lastpoint:= makepoint(0,yaxis);

  for i:= 0 to 360 do begin

   nextpoint:= makepoint(
    round(i*hstep),
    round(yaxis+sin(degtorad(i))*(clipbox.cy/2))
   );   

   linewidthmm:= 0.5;
   drawline(
    makepoint(lastpoint.x,yaxis),
    makepoint(nextpoint.x,yaxis),
    cl_red
   );

   linewidthmm:= 1.0;   
   drawline(lastpoint,nextpoint,cl_blue);
   lastpoint:= nextpoint;

  end;

 end;
end;

procedure tmainfo.paint1(const sender: twidget; const canvas: tcanvas);
 //curve drawn with disjointed lines
var
 hstep,vscale: real;    //extended is i386 only
 int1: integer;
 lastpoint, nextpoint: pointty;
begin
 with canvas do begin
  save; //save the current canvas state
  with sender.innerclientrect do begin  //canvas.cliprect is the bounding
                                  //rect of the current clip region,
                                  //it can e smaller than the widget rects.
   hstep:= cx/360;
   vscale:= -cy/2;                 //screen y direciont is inverted
   move(makepoint(x,y + cy div 2)); //set drawing origin into y center
     //default linwidth is 0 -> fastest one pixel width line drawing method.
   drawvect(nullpoint,gd_right,cx,cl_red); //base line
  end;
  lastpoint:= nullpoint;
  linewidth:= 3;       //use linewithmm only for printing (performance)
  for int1:= 0 to 360 do begin
   nextpoint.x:= round(int1*hstep);
   nextpoint.y:= round(sin(degtorad(int1))*vscale);
   drawline(lastpoint,nextpoint,cl_blue);
   lastpoint:= nextpoint;
  end;
  restore; //restore the canvas state
 end;
end;

procedure tmainfo.paint2(const sender: twidget; const canvas: tcanvas);
 //curve drawn with polyline (better)
var
 hstep,vscale: real;    //extended is i386 only
 int1: integer;
 ar1: pointarty;
begin
 with canvas do begin
  save; //save the current canvas state
  with sender.innerclientrect do begin 
   hstep:= cx/360;
   vscale:= -cy/2;                  //screen y direciont is inverted
   move(makepoint(x,y + cy div 2)); //set drawing origin into y center
     //default linwidth is 0 -> fastest one pixel width line drawing method.
   drawvect(nullpoint,gd_right,cx,cl_red);   //base line
  end;
  setlength(ar1,360+1);
  for int1:= 0 to high(ar1) do begin
   ar1[int1].x:= round(int1*hstep);
   ar1[int1].y:= round(sin(degtorad(int1))*vscale);
  end;
  linewidth:= 3;       //use linewithmm only for printing (performance)
  drawlines(ar1,false,cl_blue);
  restore; //restore the canvas state
 end;
end;



ПС:
Удобства "рисовальной" части до сих пор не были приоритетными - акцент делался на легкость написания бизнес-программ (БД,...).

Просьба, кто владеет английским хоть чуть-чуть - смело пишите в NEWS-конференцию. Заодно и и английский натренируете !
Аватара пользователя
Attid
долгожитель
Сообщения: 2589
Зарегистрирован: 27.10.2006 17:29:15
Откуда: 44°32′23.63″N 41°2′25.2″E
Контактная информация:

Сообщение Attid »

пример надо перепоковать на главную страницу.

акцент делался на легкость написания бизнес-программ (БД,...).

это и правельно, но я как раз бизнес БД приложение и пишу только подрисовать надо немного =)
Filas
незнакомец
Сообщения: 4
Зарегистрирован: 19.02.2008 21:13:10
Откуда: Санкт-Петербург

Сообщение Filas »

Переделываю свой delphi проект на mse. (В обязательном порядке нужен unicode поэтому lazarus не предлагать.)

пришлось полностью перебрать код по отрисовке изображения на paintbox, но вот вопрос. При работе проги нужно перерисовывать изображение. Никак не пойму как это сделать?
Прямое обращение к onpaint не работает, т.к. нужно указывать непонятно чей canvas.
Аватара пользователя
Attid
долгожитель
Сообщения: 2589
Зарегистрирован: 27.10.2006 17:29:15
Откуда: 44°32′23.63″N 41°2′25.2″E
Контактная информация:

Сообщение Attid »

канвас формы, он один на все про все.
хотя помнится мартин в этом направлении что-то делал.
советую идти в англоизычную конфу и там спрашивать, тут отвечает в основном деби, но он по БД проэктам специализируется.

ЗЫ MSEide+MSEgui. Урок рисования. читали в статьях ?
Filas
незнакомец
Сообщения: 4
Зарегистрирован: 19.02.2008 21:13:10
Откуда: Санкт-Петербург

Сообщение Filas »

статью о рисовании читал и использовал. покопался в исходниках.
Без этого у меня бы вообще ничего не работало и не рисовало.
Проблема в том, что у меня на форме есть paintbox и несколько окошек для ввода параметров. Надо чтобы при изменении какого-либо параметра, перерисовавалось изображение.
В делфи это решалось вызовом процедуры отрисовки в конце обработчика изменений. В MSE так не получается.

Ушел к иностранцам за ответом.
Аватара пользователя
bw
постоялец
Сообщения: 359
Зарегистрирован: 01.12.2005 10:36:23
Откуда: Усть-Илимск
Контактная информация:

Сообщение bw »

Filas, когда разберешься что да как, тут отпиши рецепт ;-).

..bw
Аватара пользователя
Attid
долгожитель
Сообщения: 2589
Зарегистрирован: 27.10.2006 17:29:15
Откуда: 44°32′23.63″N 41°2′25.2″E
Контактная информация:

Сообщение Attid »

Filas
ну вот и рисуй сначало картинку, а потом что там надо на ней без использование timage или что-то там.а событие в параметрах ончейнж.
Filas
незнакомец
Сообщения: 4
Зарегистрирован: 19.02.2008 21:13:10
Откуда: Санкт-Петербург

Сообщение Filas »

Attid
Буду признателен за точную ссылку на англоязычный форум. Не могу найти.
Аватара пользователя
Attid
долгожитель
Сообщения: 2589
Зарегистрирован: 27.10.2006 17:29:15
Откуда: 44°32′23.63″N 41°2′25.2″E
Контактная информация:

Сообщение Attid »

Forum, questions, bug reports (NNTP):

news://news.grid-sky.com/public.mseide-msegui.talk

IRC:

irc.freenode.net #mseide
Ответить