Sign in Join
Wiki copytemporary

Reference: MSEgui/TWidget: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: Reference: MSEgui/TWidget

OldNewLine
1+# TWiget
2+
3+**Ready for revision**
4+
5+Ancestor for visual components.
6+
7+## Reference
8+
9+### Hierarchy
10+
11+` TObject`\
12+`   │`\
13+`   ╰─┬─TPersistent`\
14+`     │`\
15+`     ╰─┬─TComponent`\
16+`       │`\
17+`       ╰─┬─TmseComponent`\
18+`         │`\
19+`         ╰─┬─TactComponent`\
20+`           │`\
21+`           ╰───TWidget`
22+
23+### Properties
24+
25+#### Anchors
26+
27+Anchors combines the traditional Anchors and the traditions Align properties.
28+
29+![](/wiki-images/2/20/Msegui_anchors.png)
30+
31+``` pascal
32+property anchors: anchorsty read fanchors write setanchors default defaultanchors;
33+```
34+
35+By default your anchors are an_left and an_top. Then your widget stays at the same position when sizing the form. When your widget should have a constant distance to the right border of its parent, you add an_right and remove an_left (in this order...). The same you can do with an_bottom and an_top.
36+
37+If you have only one anchor, and the widget is suitable for this sizing, the widget is using the full size of the not anchored dimension. The behaviour is near the traditional property Align, but the widget is not aligned directly to the border, but you can free position it.
38+
39+![](/wiki-images/8/8e/Msegui_an_top.png)
40+
41+By having no anchors set, the widget fills the client size of its parent (the traditional alClient).
42+
43+By setting an_left and an_top, the widget change its horizontal size by sizing its parent, the same with the vertical size by setting an_top and an_bottom together.
44+
45+#### Bounds
46+
47+The size and the position of the widget is condensed in the property bounds, but you have also the traditional properties like left an width.
48+
49+![](/wiki-images/f/fb/Msegui_bounds.png)
50+
51+``` pascal
52+// the types
53+sizety = record
54+ cx, cy: integer;
55+end;
56+
57+pointty = record
58+ x,y: integer;
59+end;
60+
61+rectty = record
62+case integer of
63+ 0: (x, y, cx, cy: integer);
64+ 1: (pos: pointty; size: sizety);
65+end;
66+
67+// the properties
68+property Widgetrect: rectty read FWidgetrect write SetWidgetrect;
69+property Pos: pointty read FWidgetrect.pos write SetPos;
70+property Size: sizety read FWidgetrect.size write SetSize;
71+
72+property Bounds_x: integer read FWidgetrect.x write SetBounds_x;
73+property Bounds_y: integer read FWidgetrect.y write SetBounds_y;
74+property Bounds_cx: integer read FWidgetrect.cx write SetBounds_cx
75+ {default defaultwidgetwidth} stored true;
76+property Bounds_cy: integer read FWidgetrect.cy write SetBounds_cy
77+ {default defaultwidgetheight} stored true;
78+property Bounds_cxmin: integer read FMinSize.cx
79+ write SetBounds_cxmin default 0;
80+property Bounds_cymin: integer read FMinSize.cy
81+ write SetBounds_cymin default 0;
82+property Bounds_cxmax: integer read FMaxSize.cx
83+ write SetBounds_cxmax default 0;
84+property Bounds_cymax: integer read FMaxSize.cy
85+ write SetBounds_cymax default 0;
86+
87+property Left: integer read FWidgetrect.x write SetBounds_x;
88+property Right: integer read GetRight write SetRight;
89+ //widgetrect.x + widgetrect.cx, sets cx if an_left is set
90+property Top: integer read FWidgetrect.y write SetBounds_y;
91+property Bottom: integer read GetBottom write SetBottom;
92+ //widgetrect.y + widgetrect.cy, sets cy if an_top is set
93+property Width: integer read FWidgetrect.cx write SetBounds_cx;
94+property Height: integer read FWidgetrect.cy write SetBounds_cy;
95+
96+property MinSize: sizety read FMinSize write SetMinSize;
97+function WidgetMinSize: sizety;
98+ //calls checkwidgetsize and frame.checkwidgetsize
99+property MaxSize: sizety read FMaxSize write SetMaxSize;
100+```
101+
102+#### Color
103+
104+``` pascal
105+property Color: colorty default defaultwidgetcolor;
106+```
107+
108+Specifies the color of the widget. With [[Reference: MSEgui/TFace|Face]] and [[Reference: MSEgui/TFrame|Frame]] other colors for the whole or a part of the widget can set.
109+
110+#### Cursor
111+
112+``` pascal
113+property Cursor: cursorshapety default cr_default;
114+```
115+
116+Specifies the look of the mouse cursor if it is over the widget.
117+
118+#### Enabled
119+
120+``` pascal
121+property Enabled: boolean default true;
122+```
123+
124+Sets the widget enabled or not. Some Widgets change their look if they are not enabled, others do not (UPDATE: Meanwhile TSlider change it's look when setting enabled).
125+
126+![](/wiki-images/3/35/Msegui_enabled.png)
127+
128+#### Face
129+
130+See [[Reference: MSEgui/TFace|TFace]]
131+
132+#### Font
133+
134+See [[Reference: MSEgui/TFont|TFont]]
135+
136+#### Frame
137+
138+See [[Reference: MSEgui/TFrame|TFrame]]
139+
140+#### Hint
141+
142+A hint is a small text displayed when the mouse cursor is over the widget. With the text editor of the object inspector you can add additional lines (SHIFT+ENTER), you can also use \[r\[n:
143+
144+``` pascal
145+Label1.Hint := 'This is a simple hin text[r[nof a simple label[r[nwith more than on line.'
146+```
147+
148+![](/wiki-images/f/f8/Msegui_widget_hint.png)
149+
150+See also [[Reference: MSEgui/TWidget|OnHint]]
151+
152+#### OptionsWidget
153+
154+``` pascal
155+optionwidgetty = (ow_background, ow_top, ow_ultratop,
156+ ow_noautosizing, //don't use, moved to optionswidget1
157+ ow_mousefocus, ow_tabfocus, ow_parenttabfocus, ow_arrowfocus,
158+ ow_arrowfocusin,ow_arrowfocusout,
159+ ow_subfocus, //reflects focus to children
160+ ow_focusbackonesc,
161+ ow_keyreturntaborder, //key_return and key_enter work like key_tab
162+ ow_nochildshortcut, //do not propagate shortcuts to parent
163+ ow_noparentshortcut, //do not react to shortcuts from parent
164+ ow_canclosenil, // don't use, moved to optionswidget1
165+ ow_mousetransparent, ow_mousewheel, ow_noscroll,
166+ ow_nochildpaintclip, ow_nochildclipsiblings,
167+ ow_destroywidgets, ow_nohidewidgets,
168+ ow_hinton, ow_hintoff, ow_disabledhint, ow_multiplehint, ow_timedhint);
169+optionswidgetty = set of optionwidgetty;
170+
171+property OptionsWidget: optionswidgetty;
172+```
173+
174+- With ow_background and ow_top you can influence the so named Z-order, also which widget is dran over another. Without that option the Z-order goes in the order of inserting the widgets on the form.
175+- The options ow_background and ow_top you can also use with forms. There you have additional the option ow_ultratop, which doesn't matter within forms.
176+- If ow_mousefocus is set, the widget can get the focus by clicking on it.
177+- If ow_tabfocus is set, the widget can get the focus using the tab key. See also TabOrder.
178+- If ow_arrowfocus is set, the widget can get the mouse focus using the arrow keys.
179+- ow_arrowfocusin and ow_arrowfocusout are for widgets with child widgets. If ow_arrowfocusin ist set, you can jump with the arrows keys into one of these child widgets, if ow_arrowfocusout is set, you can jump with the arrows keys from one of the child widgets to one outside.
180+- If a widget gets focus, ow_subfocus causes that it immediately focuses a child widget. Used for containerwidgets like TGroupBox.
181+- With ow_focusbackonesc you can set the focus to the last widget got the focus before the current one with the ESC key. (You don't go back in inverse tab order, multiple pressed ESC changes the focus between only two widgets).
182+- If you set ow_keyreturntaborder you can move in tab order with the RETURN key.
183+- If ow_mousetransparent is set, the widget itself (not the child widgets) do not react on mouse events.
184+- With ow_mousewheel you can specify, if the widget process mouse wheel events or not (provided, the widget processes mouse wheel events at all).
185+- With ow_nochildpaintclip you can draw in the Frame of your widget (it's visible if FrameColor ist cl_transparent); see the following picture:
186+
187+![](/wiki-images/3/3f/Msegui_label_nochildpaintclip.png%E2%80%8E)
188+
189+- Normally before a widget paints a child it removes the opaque areas of overlapping siblings of the child from the painting region of the canvas. ow_nochildclipsiblings inhibits this.
190+- To show a hint although the parent doesn't use ow_hinton; to do not show a hint although the parent do, use ow_hintoff.
191+- By default a disabled widget shows the hint of its parent (if it have one). To show its own hint set ow_disabledhint.
192+- By default a hint is shown only once - to see it again you have first to show the hint of another widget (or restart your application). To see the hint as often you move the mouse over the widget, use ow_multiplehint.
193+- By default the hint is shown as long as the mouse is over the widget. To hide the hint automatically set ow_timedhint.
194+
195+#### OptionsWidget1
196+
197+``` pascal
198+optionwidget1ty = (ow1_fontglyphheight, //track font.glyphheight, create fonthighdelta and childscaled events
199+ ow1_fontlineheight, //track font.linespacing, create fonthighdelta and childscaled events
200+ ow1_autoscale, //synchronizes bounds_cy or bonds_cx with fontheightdelta
201+ ow1_autowidth, ow1_autoheight,
202+ ow1_autosizeanright, ow1_noautosizeanright,
203+ ow1_autosizeanbottom, ow1_noautosizeanbottom,
204+ ow1_noparentwidthextend, ow1_noparentheightextend,
205+ ow1_canclosenil, //call canclose(nil) on exit
206+ ow1_nocancloseifhidden,
207+ ow1_modalcallonactivate, ow1_modalcallondeactivate, //used in tactionwidget
208+ ow1_noautosizing //used in tdockcontroller );
209+optionswidget1ty = set of optionwidget1ty;
210+
211+property OptionsWidget1: optionswidget1ty;
212+```
213+
214+- The meaning of ow1_autoscale shows the following picture. Please note that ow1_autowidth and ow1_autoheight aren't set. If you reduce the Font.Height from 80 to 0 (which means a default value), than the height of the widget reduces by the amount of less pixels the text is needed. Vice versa if you increase Font.Height.
215+
216+![](/wiki-images/e/ec/Msegui_label_ow1_autoscale.png)
217+
218+- ow1_autoheight causes the widget to set the height following the font size. The text to display doesn't matter.
219+- ow1_autowidth causes the widget to set the width following the font size and the text to display. At widgets like TEdit ow1_autowidth is not set by default.
220+
221+- On a left anchored widget ow1_autowidth causes the widget to extend to the right. With ow1_autosizeanright = true you can extent it to the left; see the following picture:
222+
223+![](/wiki-images/0/09/Msegui_label_ow1_autosizeanright.png%E2%80%8E)
224+
225+- On a right anchored widget ow1_autowidth causes the widget to extend to the left. With ow1_noautosizeanright = true you can extent it to the right.
226+- On a top anchored widget ow1_autoheight causes the widget to extend to the bottom. With ow1_autosizeanbottom = true you can extent it to the top.
227+- On a bottom anchored widget ow1_autoheight causes the widget to extend to the top. With ow1_noautosizeanbottom = true you can extent it to the bottom.
228+
229+- The options ow1_noparentwidthextend and ow1_noparentheightextend are usually used together with scrolling widgets like TScrollBox or with TExpandingWidget. These widgets change their size or scrolling area regarding to their child widgets. If you want to take a widget not in account to define the width, set ow1_noparentwidthextend, the same for the height with ow1_noparentheightextend.
230+
231+- If ow1_canclosenil is set, the function CanClose with NIL as "newfocus" parameter is additionally executed when the Widget should loose the focus. To inhibit this, the function have to return false. The virtual function CanClose returns true by default, but can be overrided and also execute CanClose of all child widgets. TWidget.CanClose(\<newfocusedwidget\>) is called anyway by changing the focused widget in a form. ow1_canclosenil additionally calls canclose(nil) which simulates closing the form. Some widgets distinguish between loosing focus to another widget of the form or by closing the form. For example in a data entry form mandatory fields need to be checked for CanClose(nil).
232+
233+- To prevent CanClose from doing anything if the widget is not visible, set ow1_nocancloseifhidden.
234+
235+- If a form is shown modal, it gets the activation if it is shown and it loose the activation on closing. Inbetween there is no activation change. Therefore the events OnActivate and OnDeactivate are normally not triggered on modal widgets. To do this yet, use ow1_modalcallonactivate and ow1_modalcallondeactivate.
236+
237+#### PopupMenu
238+
239+Reference on a TPopupMenu instance, showing with a rightclick on the widget. See also [[Reference: MSEgui/TWidget|OnPopup]]
240+
241+``` pascal
242+property PopupMenu: TPopupMenu;
243+```
244+
245+#### TabOrder
246+
247+``` pascal
248+property TabOrder: integer;
249+```
250+
251+Specifys in which order the widgets get the focus if you use the tab key. (See also ow_tabfocus in OptionsWidget.)
252+
253+#### Visible
254+
255+``` pascal
256+property Visible: boolean default true;
257+```
258+
259+Sets the widget visible or hides it.
260+
261+### Methods
262+
263+Please suggest here methodes to describe wich are used for working with the widget, not for internal.
264+
265+### Events
266+
267+#### OnHint
268+
269+``` pascal
270+showhinteventty = procedure(const Sender: TObject; var Info: hintinfoty) of object;
271+```
272+
273+The event OnHint is triggered, when a hint is displayed for the widget. With the var-parameter Info you can specify details of the displayed hint.
274+
275+``` pascal
276+procedure tmainfo.FormShowHint(const Sender: TObject; var Info: hintinfoty);
277+begin
278+ Info.Caption := 'Trololo';
279+ Info.PosRect.X := Info.PosRect.X + 60;
280+ Info.PosRect.y := Info.PosRect.y - 20;
281+end;
282+```
283+
284+![](/wiki-images/3/37/Msegui_widget_hint2.png)
285+
286+#### OnEnter, OnFocus, OnActivate
287+
288+We have three pairs of events regarding the change of a focus:
289+
290+``` pascal
291+property OnEnter: notifyeventty;
292+property OnExit: notifyeventty;
293+
294+property OnFocus: notifyeventty;
295+property OnDeFocus: notifyeventty;
296+
297+property OnActivate: notifyeventty;
298+property OnDeActivate: notifyeventty;
299+```
300+
301+For an example we have two forms with both have two edits. The main form has an memo to log the events (here an example for OnEnter):
302+
303+``` pascal
304+procedure ttestfo.FormEnter(const Sender: TObject);
305+begin
306+ MainFo.DoLog((Sender as TWidget).Name + ' OnEnter');
307+end;
308+```
309+
310+We click on the first form:
311+
312+- Form1 OnEnter
313+- Form1_Edit1 OnEnter
314+- Form1_Edit1 OnFocus
315+- Form1 OnActivate
316+- Form1_Edit1 OnActivate
317+
318+Now we click on the second edit of the first form:
319+
320+- Form1_Edit1 OnDeFocus
321+- Form1_Edit1 OnDeActivate
322+- Form1_Edit1 OnExit
323+- Form1_Edit2 OnEnter
324+- Form1_Edit2 OnActivate
325+- Form1_Edit2 OnFocus
326+
327+Now we click on then second form:
328+
329+- Form2 OnEnter
330+- Form2_Edit1 OnEnter
331+- Form2_Edit1 OnFocus
332+- Form1_Edit2 OnDeActivate
333+- Form1 OnDeActivate
334+- Form2 OnActivate
335+- Form2_Edit1 OnActivate
336+
337+Now we click on the second edit of the first form (which was formerly focused on the first form):
338+
339+- Form2_Edit1 OnDeActivate
340+- Form2 OnDeActivate
341+- Form1 OnActivate
342+- Form1_Edit2 OnActivate
343+
344+And now we click on the second edit for the second form:
345+
346+- Form1_Edit2 OnDeActivate
347+- Form1 OnDeActivate
348+- Form2 OnActivate
349+- Form2_Edit1 OnActivate
350+- Form2_Edit1 OnDeFocus
351+- Form2_Edit1 OnDeActivate
352+- Form2_Edit1 OnExit
353+- Form2_Edit2 OnEnter
354+- Form2_Edit2 OnActivate
355+- Form2_Edit2 OnFocus
356+
357+In the last step we see first an complete activation change of the form (goes to Form2_Edit1) and than a complete focus change from Form2_Edit1 to Form2_Edit2.
358+
359+We see:
360+
361+- OnFocus and OnDeFocus only the widget which have the focus, here TEdit.
362+- OnEnter is the first event if a widget gets the focus, OnEnter is the last event if a widget loose the focus. On a focus change, OnEnter of the focus getting widget is following directly on OnExit of the focus loosing widget.
363+- Changing the form fires only OnActivate and OnDeActivate (but not only the changing of the forms fires them). (First OnDeactivate of the widget, than OnDeactivate of the form, then OnActivate of the form, then OnActvate of the widget.)
364+
365+#### OnNavigRequest
366+
367+If ow_ArrowFocus is in OptionsWidget of the regarding widgets, you can change the focus with the arrow keys. The parent component has an algorithm to select the next widget for each arrow key, and at the end of this algorithm the event OnNavigRequest is fired. Here you can overwrite some values.
368+
369+``` pascal
370+graphicdirectionty = (gd_right,gd_up,gd_left,gd_down,gd_none);
371+
372+naviginfoty = record
373+ sender: twidget;
374+ direction: graphicdirectionty;
375+ startingrect: rectty;
376+ distance: integer;
377+ nearest: twidget;
378+ down: boolean;
379+ hastarget: boolean;
380+end;
381+
382+navigrequesteventty = procedure(const Sender: twidget; var AInfo: naviginfoty) of object;
383+
384+property OnNavigRequest: navigrequesteventty
385+```
386+
387+The most likely case may be, that you want to set the focus to another widget. In the following example the focus goes always to Edit9. Make sure, that you use the OnNavigRequest of the parent widget.
388+
389+``` pascal
390+procedure tmainfo.FormNavigRequest(const Sender: TWidget; var AInfo: naviginfoty);
391+begin
392+ AInfo.Nearest := Edit9;
393+end;
394+```
395+
396+#### OnPaint, OnPaintBackground, OnAfterPaint, OnPaintBackground
397+
398+The OnPaint-Events are fired before, while or after the widget is painted.
399+
400+``` pascal
401+painteventty = procedure (const Sender: TWidget; const ACanvas: TCanvas) of object;
402+
403+property OnBeforePaint: painteventty;
404+property OnPaintBackground: painteventty;
405+property OnPaint: painteventty;
406+property OnAfterPaint: painteventty;
407+```
408+
409+The following example shows, when the events are fired:
410+
411+- The first is OnBeforePaint. You don't see the green line, cause its overdrawn, but you see the two following lines with a width of 3.
412+- The next is OnPaintBackground. You see the yellow line, but the Caption of the button is drawn over it.
413+- OnPaint is drawn after the Caption is drawn, the red line is over it.
414+- The last is OnAfterPaint, its fired after the frame is drawn so you can draw over the frame. The line width is resetted, if you want a higher line width, you have set it new.
415+
416+``` pascal
417+procedure tmainfo.LabelPaint(const Sender: TWidget; const ACanvas: TCanvas);
418+begin
419+ ACanvas.DrawLine(mp(-30, -30), mp(150, 150), cl_red);
420+end;
421+
422+procedure tmainfo.LabelAfterPaint(const Sender: TWidget; const ACanvas: TCanvas);
423+begin
424+ ACanvas.DrawLine(mp(-25, -30), mp(155, 150), cl_blue);
425+end;
426+
427+procedure tmainfo.LabelBeforePaint(const Sender: TWidget; const ACanvas: TCanvas);
428+begin
429+ ACanvas.LineWidth := 3;
430+ ACanvas.DrawLine(mp(-20, -30), mp(160, 150), cl_green);
431+end;
432+
433+procedure tmainfo.LabelPaintBackground(const Sender: TWidget; const ACanvas: TCanvas);
434+begin
435+ ACanvas.DrawLine(mp(-15, -30), mp(165, 150), cl_yellow);
436+end;
437+```
438+
439+![](/wiki-images/7/7c/Msegui_label_onpaint.png)
440+
441+#### OnPopup
442+
443+The event OnPopup is fired if you show the PopupMenu by clicking with the right mouse button, but not, if you show the PopupMenu manually by TPopupMenu.Show.
444+
445+``` pascal
446+popupeventty = procedure(const Sender: TObject; var AMenu: TPopupMenu; var MouseInfo: mouseeventinfoty) of object;
447+```
448+
449+You can use AMenu to assign a TPopupMenu-Instance in this moment. With MouseInfo you have some information like Position or shift state and can also change them:
450+
451+``` pascal
452+procedure tmainfo.LabelPopup(const Sender: TObject; var AMenu: TPopupMenu; var MouseInfo: mouseeventinfoty);
453+begin
454+ AMenu := PopupMenu1;
455+ MouseInfo.Pos.X := MouseInfo.Pos.X + 300;
456+end;
457+```
458+
459+#### OnBeforeUpdateSkin, OnAfterUpdateSkin
460+
461+Inherited from TMseComponent: [[Reference: MSEgui/TMseComponent|OnBeforeUpdateSkin, OnAfterUpdateSkin]]
462+
463+## Known issues
464+
465+### Issues of the class
466+
467+### Issues of this documentation
468+
469+Feel free to add your points here.
470+
471+---
472+*From the Free Pascal wiki, page "Reference: MSEgui/TWidget", as it stood on 2020-02-25 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
473+Category: MSEide+MSEgui

Back to history