Sign in Join
Wiki copytemporary

Reference: MSEgui/TWidget: what changed

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

OldNewLine
11# TWiget
22
33**Ready for revision**
44
55Ancestor for visual components.
66
77## Reference
88
99### Hierarchy
1010
11-` TObject`\
12-`   │`\
13-`   ╰─┬─TPersistent`\
14-`     │`\
15-`     ╰─┬─TComponent`\
16-`       │`\
17-`       ╰─┬─TmseComponent`\
18-`         │`\
19-`         ╰─┬─TactComponent`\
20-`           │`\
21-`           ╰───TWidget`
11+```text
12+ TObject
13+ │
14+ ╰─┬─TPersistent
15+ │
16+ ╰─┬─TComponent
17+ │
18+ ╰─┬─TmseComponent
19+ │
20+ ╰─┬─TactComponent
21+ │
22+ ╰───TWidget
23+```
2224
2325### Properties
2426
2527#### Anchors
2628
2729Anchors combines the traditional Anchors and the traditions Align properties.
2830
2931![](/wiki-images/2/20/Msegui_anchors.png)
3032
3133``` pascal
3234property anchors: anchorsty read fanchors write setanchors default defaultanchors;
3335```
3436
3537By 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.
3638
3739If 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.
3840
3941![](/wiki-images/8/8e/Msegui_an_top.png)
4042
4143By having no anchors set, the widget fills the client size of its parent (the traditional alClient).
4244
4345By 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.
4446
4547#### Bounds
4648
4749The size and the position of the widget is condensed in the property bounds, but you have also the traditional properties like left an width.
4850
4951![](/wiki-images/f/fb/Msegui_bounds.png)
5052
5153``` pascal
5254// the types
5355sizety = record
5456 cx, cy: integer;
5557end;
5658
5759pointty = record
5860 x,y: integer;
5961end;
6062
6163rectty = record
6264case integer of
6365 0: (x, y, cx, cy: integer);
6466 1: (pos: pointty; size: sizety);
6567end;
6668
6769// the properties
6870property Widgetrect: rectty read FWidgetrect write SetWidgetrect;
6971property Pos: pointty read FWidgetrect.pos write SetPos;
7072property Size: sizety read FWidgetrect.size write SetSize;
7173
7274property Bounds_x: integer read FWidgetrect.x write SetBounds_x;
7375property Bounds_y: integer read FWidgetrect.y write SetBounds_y;
7476property Bounds_cx: integer read FWidgetrect.cx write SetBounds_cx
7577 {default defaultwidgetwidth} stored true;
7678property Bounds_cy: integer read FWidgetrect.cy write SetBounds_cy
7779 {default defaultwidgetheight} stored true;
7880property Bounds_cxmin: integer read FMinSize.cx
7981 write SetBounds_cxmin default 0;
8082property Bounds_cymin: integer read FMinSize.cy
8183 write SetBounds_cymin default 0;
8284property Bounds_cxmax: integer read FMaxSize.cx
8385 write SetBounds_cxmax default 0;
8486property Bounds_cymax: integer read FMaxSize.cy
8587 write SetBounds_cymax default 0;
8688
8789property Left: integer read FWidgetrect.x write SetBounds_x;
8890property Right: integer read GetRight write SetRight;
8991 //widgetrect.x + widgetrect.cx, sets cx if an_left is set
9092property Top: integer read FWidgetrect.y write SetBounds_y;
9193property Bottom: integer read GetBottom write SetBottom;
9294 //widgetrect.y + widgetrect.cy, sets cy if an_top is set
9395property Width: integer read FWidgetrect.cx write SetBounds_cx;
9496property Height: integer read FWidgetrect.cy write SetBounds_cy;
9597
9698property MinSize: sizety read FMinSize write SetMinSize;
9799function WidgetMinSize: sizety;
98100 //calls checkwidgetsize and frame.checkwidgetsize
99101property MaxSize: sizety read FMaxSize write SetMaxSize;
100102```
101103
102104#### Color
103105
104106``` pascal
105107property Color: colorty default defaultwidgetcolor;
106108```
107109
108110Specifies 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.
109111
110112#### Cursor
111113
112114``` pascal
113115property Cursor: cursorshapety default cr_default;
114116```
115117
116118Specifies the look of the mouse cursor if it is over the widget.
117119
118120#### Enabled
119121
120122``` pascal
121123property Enabled: boolean default true;
122124```
123125
124126Sets 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).
125127
126128![](/wiki-images/3/35/Msegui_enabled.png)
127129
128130#### Face
129131
130132See [[Reference: MSEgui/TFace|TFace]]
131133
132134#### Font
133135
134136See [[Reference: MSEgui/TFont|TFont]]
135137
136138#### Frame
137139
138140See [[Reference: MSEgui/TFrame|TFrame]]
139141
140142#### Hint
141143
142144A 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:
143145
144146``` pascal
145147Label1.Hint := 'This is a simple hin text[r[nof a simple label[r[nwith more than on line.'
146148```
147149
148150![](/wiki-images/f/f8/Msegui_widget_hint.png)
149151
150152See also [[Reference: MSEgui/TWidget|OnHint]]
151153
152154#### OptionsWidget
153155
154156``` pascal
155157optionwidgetty = (ow_background, ow_top, ow_ultratop,
156158 ow_noautosizing, //don't use, moved to optionswidget1
157159 ow_mousefocus, ow_tabfocus, ow_parenttabfocus, ow_arrowfocus,
158160 ow_arrowfocusin,ow_arrowfocusout,
159161 ow_subfocus, //reflects focus to children
160162 ow_focusbackonesc,
161163 ow_keyreturntaborder, //key_return and key_enter work like key_tab
162164 ow_nochildshortcut, //do not propagate shortcuts to parent
163165 ow_noparentshortcut, //do not react to shortcuts from parent
164166 ow_canclosenil, // don't use, moved to optionswidget1
165167 ow_mousetransparent, ow_mousewheel, ow_noscroll,
166168 ow_nochildpaintclip, ow_nochildclipsiblings,
167169 ow_destroywidgets, ow_nohidewidgets,
168170 ow_hinton, ow_hintoff, ow_disabledhint, ow_multiplehint, ow_timedhint);
169171optionswidgetty = set of optionwidgetty;
170172
171173property OptionsWidget: optionswidgetty;
172174```
173175
174176- 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.
175177- 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.
176178- If ow_mousefocus is set, the widget can get the focus by clicking on it.
177179- If ow_tabfocus is set, the widget can get the focus using the tab key. See also TabOrder.
178180- If ow_arrowfocus is set, the widget can get the mouse focus using the arrow keys.
179181- 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.
180182- If a widget gets focus, ow_subfocus causes that it immediately focuses a child widget. Used for containerwidgets like TGroupBox.
181183- 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).
182184- If you set ow_keyreturntaborder you can move in tab order with the RETURN key.
183185- If ow_mousetransparent is set, the widget itself (not the child widgets) do not react on mouse events.
184186- With ow_mousewheel you can specify, if the widget process mouse wheel events or not (provided, the widget processes mouse wheel events at all).
185187- With ow_nochildpaintclip you can draw in the Frame of your widget (it's visible if FrameColor ist cl_transparent); see the following picture:
186188
187189![](/wiki-images/3/3f/Msegui_label_nochildpaintclip.png%E2%80%8E)
188190
189191- 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.
190192- 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.
191193- By default a disabled widget shows the hint of its parent (if it have one). To show its own hint set ow_disabledhint.
192194- 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.
193195- By default the hint is shown as long as the mouse is over the widget. To hide the hint automatically set ow_timedhint.
194196
195197#### OptionsWidget1
196198
197199``` pascal
198200optionwidget1ty = (ow1_fontglyphheight, //track font.glyphheight, create fonthighdelta and childscaled events
199201 ow1_fontlineheight, //track font.linespacing, create fonthighdelta and childscaled events
200202 ow1_autoscale, //synchronizes bounds_cy or bonds_cx with fontheightdelta
201203 ow1_autowidth, ow1_autoheight,
202204 ow1_autosizeanright, ow1_noautosizeanright,
203205 ow1_autosizeanbottom, ow1_noautosizeanbottom,
204206 ow1_noparentwidthextend, ow1_noparentheightextend,
205207 ow1_canclosenil, //call canclose(nil) on exit
206208 ow1_nocancloseifhidden,
207209 ow1_modalcallonactivate, ow1_modalcallondeactivate, //used in tactionwidget
208210 ow1_noautosizing //used in tdockcontroller );
209211optionswidget1ty = set of optionwidget1ty;
210212
211213property OptionsWidget1: optionswidget1ty;
212214```
213215
214216- 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.
215217
216218![](/wiki-images/e/ec/Msegui_label_ow1_autoscale.png)
217219
218220- ow1_autoheight causes the widget to set the height following the font size. The text to display doesn't matter.
219221- 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.
220222
221223- 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:
222224
223225![](/wiki-images/0/09/Msegui_label_ow1_autosizeanright.png%E2%80%8E)
224226
225227- 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.
226228- 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.
227229- 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.
228230
229231- 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.
230232
231233- 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).
232234
233235- To prevent CanClose from doing anything if the widget is not visible, set ow1_nocancloseifhidden.
234236
235237- 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.
236238
237239#### PopupMenu
238240
239241Reference on a TPopupMenu instance, showing with a rightclick on the widget. See also [[Reference: MSEgui/TWidget|OnPopup]]
240242
241243``` pascal
242244property PopupMenu: TPopupMenu;
243245```
244246
245247#### TabOrder
246248
247249``` pascal
248250property TabOrder: integer;
249251```
250252
251253Specifys in which order the widgets get the focus if you use the tab key. (See also ow_tabfocus in OptionsWidget.)
252254
253255#### Visible
254256
255257``` pascal
256258property Visible: boolean default true;
257259```
258260
259261Sets the widget visible or hides it.
260262
261263### Methods
262264
263265Please suggest here methodes to describe wich are used for working with the widget, not for internal.
264266
265267### Events
266268
267269#### OnHint
268270
269271``` pascal
270272showhinteventty = procedure(const Sender: TObject; var Info: hintinfoty) of object;
271273```
272274
273275The 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.
274276
275277``` pascal
276278procedure tmainfo.FormShowHint(const Sender: TObject; var Info: hintinfoty);
277279begin
278280 Info.Caption := 'Trololo';
279281 Info.PosRect.X := Info.PosRect.X + 60;
280282 Info.PosRect.y := Info.PosRect.y - 20;
281283end;
282284```
283285
284286![](/wiki-images/3/37/Msegui_widget_hint2.png)
285287
286288#### OnEnter, OnFocus, OnActivate
287289
288290We have three pairs of events regarding the change of a focus:
289291
290292``` pascal
291293property OnEnter: notifyeventty;
292294property OnExit: notifyeventty;
293295
294296property OnFocus: notifyeventty;
295297property OnDeFocus: notifyeventty;
296298
297299property OnActivate: notifyeventty;
298300property OnDeActivate: notifyeventty;
299301```
300302
301303For 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):
302304
303305``` pascal
304306procedure ttestfo.FormEnter(const Sender: TObject);
305307begin
306308 MainFo.DoLog((Sender as TWidget).Name + ' OnEnter');
307309end;
308310```
309311
310312We click on the first form:
311313
312314- Form1 OnEnter
313315- Form1_Edit1 OnEnter
314316- Form1_Edit1 OnFocus
315317- Form1 OnActivate
316318- Form1_Edit1 OnActivate
317319
318320Now we click on the second edit of the first form:
319321
320322- Form1_Edit1 OnDeFocus
321323- Form1_Edit1 OnDeActivate
322324- Form1_Edit1 OnExit
323325- Form1_Edit2 OnEnter
324326- Form1_Edit2 OnActivate
325327- Form1_Edit2 OnFocus
326328
327329Now we click on then second form:
328330
329331- Form2 OnEnter
330332- Form2_Edit1 OnEnter
331333- Form2_Edit1 OnFocus
332334- Form1_Edit2 OnDeActivate
333335- Form1 OnDeActivate
334336- Form2 OnActivate
335337- Form2_Edit1 OnActivate
336338
337339Now we click on the second edit of the first form (which was formerly focused on the first form):
338340
339341- Form2_Edit1 OnDeActivate
340342- Form2 OnDeActivate
341343- Form1 OnActivate
342344- Form1_Edit2 OnActivate
343345
344346And now we click on the second edit for the second form:
345347
346348- Form1_Edit2 OnDeActivate
347349- Form1 OnDeActivate
348350- Form2 OnActivate
349351- Form2_Edit1 OnActivate
350352- Form2_Edit1 OnDeFocus
351353- Form2_Edit1 OnDeActivate
352354- Form2_Edit1 OnExit
353355- Form2_Edit2 OnEnter
354356- Form2_Edit2 OnActivate
355357- Form2_Edit2 OnFocus
356358
357359In 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.
358360
359361We see:
360362
361363- OnFocus and OnDeFocus only the widget which have the focus, here TEdit.
362364- 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.
363365- 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.)
364366
365367#### OnNavigRequest
366368
367369If 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.
368370
369371``` pascal
370372graphicdirectionty = (gd_right,gd_up,gd_left,gd_down,gd_none);
371373
372374naviginfoty = record
373375 sender: twidget;
374376 direction: graphicdirectionty;
375377 startingrect: rectty;
376378 distance: integer;
377379 nearest: twidget;
378380 down: boolean;
379381 hastarget: boolean;
380382end;
381383
382384navigrequesteventty = procedure(const Sender: twidget; var AInfo: naviginfoty) of object;
383385
384386property OnNavigRequest: navigrequesteventty
385387```
386388
387389The 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.
388390
389391``` pascal
390392procedure tmainfo.FormNavigRequest(const Sender: TWidget; var AInfo: naviginfoty);
391393begin
392394 AInfo.Nearest := Edit9;
393395end;
394396```
395397
396398#### OnPaint, OnPaintBackground, OnAfterPaint, OnPaintBackground
397399
398400The OnPaint-Events are fired before, while or after the widget is painted.
399401
400402``` pascal
401403painteventty = procedure (const Sender: TWidget; const ACanvas: TCanvas) of object;
402404
403405property OnBeforePaint: painteventty;
404406property OnPaintBackground: painteventty;
405407property OnPaint: painteventty;
406408property OnAfterPaint: painteventty;
407409```
408410
409411The following example shows, when the events are fired:
410412
411413- 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.
412414- The next is OnPaintBackground. You see the yellow line, but the Caption of the button is drawn over it.
413415- OnPaint is drawn after the Caption is drawn, the red line is over it.
414416- 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.
415417
416418``` pascal
417419procedure tmainfo.LabelPaint(const Sender: TWidget; const ACanvas: TCanvas);
418420begin
419421 ACanvas.DrawLine(mp(-30, -30), mp(150, 150), cl_red);
420422end;
421423
422424procedure tmainfo.LabelAfterPaint(const Sender: TWidget; const ACanvas: TCanvas);
423425begin
424426 ACanvas.DrawLine(mp(-25, -30), mp(155, 150), cl_blue);
425427end;
426428
427429procedure tmainfo.LabelBeforePaint(const Sender: TWidget; const ACanvas: TCanvas);
428430begin
429431 ACanvas.LineWidth := 3;
430432 ACanvas.DrawLine(mp(-20, -30), mp(160, 150), cl_green);
431433end;
432434
433435procedure tmainfo.LabelPaintBackground(const Sender: TWidget; const ACanvas: TCanvas);
434436begin
435437 ACanvas.DrawLine(mp(-15, -30), mp(165, 150), cl_yellow);
436438end;
437439```
438440
439441![](/wiki-images/7/7c/Msegui_label_onpaint.png)
440442
441443#### OnPopup
442444
443445The 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.
444446
445447``` pascal
446448popupeventty = procedure(const Sender: TObject; var AMenu: TPopupMenu; var MouseInfo: mouseeventinfoty) of object;
447449```
448450
449451You 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:
450452
451453``` pascal
452454procedure tmainfo.LabelPopup(const Sender: TObject; var AMenu: TPopupMenu; var MouseInfo: mouseeventinfoty);
453455begin
454456 AMenu := PopupMenu1;
455457 MouseInfo.Pos.X := MouseInfo.Pos.X + 300;
456458end;
457459```
458460
459461#### OnBeforeUpdateSkin, OnAfterUpdateSkin
460462
461463Inherited from TMseComponent: [[Reference: MSEgui/TMseComponent|OnBeforeUpdateSkin, OnAfterUpdateSkin]]
462464
463465## Known issues
464466
465467### Issues of the class
466468
467469### Issues of this documentation
468470
469471Feel free to add your points here.
470472
471473---
472474*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).*
473475Category: MSEide+MSEgui

Back to history