topic "GUI Tutorial";
[2 $$0,0#00000000000000000000000000000000:Default]
[l288;i1120;a17;O9;~~~.1408;2 $$1,0#10431211400427159095818037425705:param]
[a83;*R6 $$2,5#31310162474203024125188417583966:caption]
[H4;b83;*4 $$3,5#07864147445237544204411237157677:title]
[i288;O9;C2 $$4,6#40027414424643823182269349404212:item]
[b42;a42;ph2 $$5,5#45413000475342174754091244180557:text]
[l288;b17;a17;2 $$6,6#27521748481378242620020725143825:desc]
[l321;C@5;1 $$7,7#20902679421464641399138805415013:code]
[b2503;2 $$8,0#65142375456100023862071332075487:separator]
[*@(0.0.255)2 $$9,0#83433469410354161042741608181528:base]
[C2 $$10,0#37138531426314131251341829483380:class]
[l288;a17;*1 $$11,11#70004532496200323422659154056402:requirement]
[i417;b42;a42;O9;~~~.416;2 $$12,12#10566046415157235020018451313112:tparam]
[b167;C2 $$13,13#92430459443460461911108080531343:item1]
[i288;a42;O9;C2 $$14,14#77422149456609303542238260500223:item2]
[*@2$(0.128.128)2 $$15,15#34511555403152284025741354420178:NewsDate]
[l321;*C$7;2 $$16,16#03451589433145915344929335295360:result]
[l321;b83;a83;*C$7;2 $$17,17#07531550463529505371228428965313:result`-line]
[l160;*C+117 $$18,5#88603949442205825958800053222425:package`-title]
[2 $$19,0#53580023442335529039900623488521:gap]
[C2 $$20,20#70211524482531209251820423858195:class`-nested]
[b50;2 $$21,21#03324558446220344731010354752573:Par]
[{_}%EN-US 
[s2; GUI Tutorial&]
[s5;~~~2240; Welcome in GUI Tutorial! Here you will learn how to 
write GUI applications using U`+`+ library. All code mentions 
in this tutorial is multi platform. It means it works exactly 
the same on different operating system. Moreover, examples attached 
in this tutorial are bundle with U`+`+ standard distribution 
and they are localized in [* tutorial] assembly. So, you don`'t 
need to rewrite it by yourself. Good luck!&]
[s3; Table of contents&]
[s0; &]
[s0; [^topic`:`/`/CtrlLib`/srcdoc`/Tutorial`$en`-us`#1^ 1. GUI application 
main function]&]
[s0; [^topic`:`/`/CtrlLib`/srcdoc`/Tutorial`$en`-us`#2^ 2. Application 
window]&]
[s0; [^topic`:`/`/CtrlLib`/srcdoc`/Tutorial`$en`-us`#3^ 3. Modifying 
TopWindow properties]&]
[s0; [^topic`:`/`/CtrlLib`/srcdoc`/Tutorial`$en`-us`#4^ 4. Painting 
the view area]&]
[s0; [^topic`:`/`/CtrlLib`/srcdoc`/Tutorial`$en`-us`#5^ 5. Reacting 
to input events]&]
[s0; [^topic`:`/`/CtrlLib`/srcdoc`/Tutorial`$en`-us`#6^ 6. Multiple 
main windows]&]
[s0; [^topic`:`/`/CtrlLib`/srcdoc`/Tutorial`$en`-us`#7^ 7. Menu]&]
[s0; [^topic`:`/`/CtrlLib`/srcdoc`/Tutorial`$en`-us`#8^ 8. Context 
menu]&]
[s0; [^topic`:`/`/CtrlLib`/srcdoc`/Tutorial`$en`-us`#9^ 9. Context 
menu alternative]&]
[s0; [^topic`:`/`/CtrlLib`/srcdoc`/Tutorial`$en`-us`#10^ 10. Adding 
images]&]
[s0; [^topic`:`/`/CtrlLib`/srcdoc`/Tutorial`$en`-us`#11^ 11. Toolbar]&]
[s0; [^topic`:`/`/CtrlLib`/srcdoc`/Tutorial`$en`-us`#12^ 12. StatusBar 
and decorative Frames]&]
[s0; [^topic`:`/`/CtrlLib`/srcdoc`/Tutorial`$en`-us`#13^ 13. Adding 
child Ctrls `- widgets, reacting to widget events]&]
[s0; [^topic`:`/`/CtrlLib`/srcdoc`/Tutorial`$en`-us`#14^ 14. More about 
logical coordinates]&]
[s0; [^topic`:`/`/CtrlLib`/srcdoc`/Tutorial`$en`-us`#15^ 15. Font`-zoomed 
logical coordinates]&]
[s0; [^topic`:`/`/CtrlLib`/srcdoc`/Tutorial`$en`-us`#16^ 16. Layouts]&]
[s0; [^topic`:`/`/CtrlLib`/srcdoc`/Tutorial`$en`-us`#17^ 17. Value 
of widget]&]
[s0; [^topic`:`/`/CtrlLib`/srcdoc`/Tutorial`$en`-us`#18^ 18. Accepting 
and rejecting widgets]&]
[s0; [^topic`:`/`/CtrlLib`/srcdoc`/Tutorial`$en`-us`#19^ 19. Widget 
edit status flags]&]
[s0; [^topic`:`/`/CtrlLib`/srcdoc`/Tutorial`$en`-us`#20^ 20. Breaking 
the modal loop]&]
[s0; [^topic`:`/`/CtrlLib`/srcdoc`/Tutorial`$en`-us`#21^ 21. Creating 
and using custom widgets]&]
[s0; [^topic`:`/`/CtrlLib`/srcdoc`/Tutorial`$en`-us`#22^ 22. Non`-modal 
dialogs]&]
[s0; &]
[s3;:1: 1. GUI application main function&]
[s5; To hide platform specific differences, U`+`+ GUI application 
main function is defined using [* GUI`_APP`_MAIN] macro:&]
[s5; &]
[s7; #include <CtrlLib/CtrlLib.h>&]
[s7; &]
[s7; using namespace Upp;&]
[s7; &]
[s7; [* GUI`_APP`_MAIN] `{&]
[s7; -|PromptOK(`"Hello world`");&]
[s7; `}&]
[s5; &]
[s0;= 
@@rawimage:1068&818
([encoded data, 4820 characters])
&]
[s5; &]
[s5; Please notice that [* PromptOK] function display simply information 
dialog with the given parameter in this case it is `"Hello world`". 
Of course, in the [* CtrlLib ]package, there are more similar library 
calls. For example `- if you want to display an error you can 
use [* ErrorOK ]and for warnings it is corresponding [* Exclamation 
]function.&]
[s5; To use U`+`+ GUI related code, all you need to do is include 
[*/ <CtrlLib/CtrlLib.h>] header. Please also make sure that [* CtrlLib 
]package is attached to your current project.&]
[s5; &]
[s3;:2: 2. Application window&]
[s5; Application top`-level windows are of [* TopWindow] class. You 
can run modal event loop for [* TopWindow] using the [* Run] or [* Execute] 
methods. Both methods open the window if it is not yet open (you 
can also open it using [* Open] or [* OpenMain]). Unlike [* Run], [* Execute] 
also closes the window at the end of modal loop. [* TopWindow] 
is also closed by destructor.&]
[s5; &]
[s7; #include <CtrlLib/CtrlLib.h>&]
[s7; &]
[s7; using namespace Upp;&]
[s7; &]
[s7; GUI`_APP`_MAIN `{&]
[s7; -|[* TopWindow] w;&]
[s7; -|w.[* Run]();&]
[s7; `}&]
[s5; &]
[s0;= 
@@rawimage:2692&1419
([encoded data, 7072 characters])
&]
[s5; &]
[s3;:3: 3. Modifying TopWindow properties&]
[s5; You can modify properties and behaviour of [* TopWindow] using 
`"modifier`" methods. Note that modifiers usually return `*this 
as return value, which results in simplified syntax. You can 
also setup the size of [* TopWindow] using [* SetRect] (note that 
unless instructed otherwise, U`+`+ will center the position of 
window).&]
[s5; &]
[s7; #include <CtrlLib/CtrlLib.h>&]
[s7; &]
[s7; using namespace Upp;&]
[s7; &]
[s7; GUI`_APP`_MAIN&]
[s7; `{&]
[s7; -|TopWindow w;&]
[s7; -|w.[* Title](`"My application`").[* MinimizeBox]().[* Sizeable]();&]
[s7; -|w.[* SetRect](0, 0, 200, 300);&]
[s7; -|w.Run();&]
[s7; `}&]
[s5; &]
[s0;= 
@@rawimage:2000&1085
(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)
&]
[s5; &]
[s3;:4: 4. Painting the view area&]
[s5; In order to display something inside [* TopWindow] view area, 
you have to create derived class and override [* Paint] method:&]
[s5; &]
[s7; #include <CtrlLib/CtrlLib.h>&]
[s7; &]
[s7; using namespace Upp;&]
[s7; &]
[s7; struct MyAppWindow : TopWindow `{&]
[s7; [* -|virtual void Paint(Draw`& w) `{]&]
[s7; [* -|-|w.DrawRect(GetSize(), SWhite);]&]
[s7; [* -|-|w.DrawText(20, 20, `"Hello world!`", Arial(30), Magenta);]&]
[s7; [* -|`}]&]
[s7; -|&]
[s7; -|MyAppWindow() `{&]
[s7; -|-|Title(`"My application`").Zoomable().Sizeable();&]
[s7; -|`}&]
[s7; `};&]
[s7; &]
[s7; GUI`_APP`_MAIN&]
[s7; `{&]
[s7; -|MyAppWindow app;&]
[s7; -|app.SetRect(0, 0, 200, 100);&]
[s7; -|app.Run();&]
[s7; `}&]
[s5; &]
[s0;= 
@@rawimage:1426&573
(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)
 &]
[s0;= &]
[s0;= 
@@rawimage:1675&695
([encoded data, 10108 characters])
&]
[s5;=l288;r224; The same application running in different operating 
systems. On the top MS Windows and on the bottom GNU/Linux with 
KDE.&]
[s5; &]
[s3;:5: 5. Reacting to input events&]
[s5; In order to react to user actions like mouse clicks or keyboard 
events, you have to override appropriate virtual methods. To 
issue the repainting of view area, use the [* Refresh] method.&]
[s5; &]
[s7; #include <CtrlLib/CtrlLib.h>&]
[s7; &]
[s7; using namespace Upp;&]
[s7; &]
[s7; struct MyAppWindow : TopWindow `{&]
[s7; -|Point  p;&]
[s7; -|String text;&]
[s7; -|&]
[s7; [* -|virtual void LeftDown(Point pos, dword flags) `{]&]
[s7; [* -|-|p `= pos;]&]
[s7; [* -|-|Refresh();]&]
[s7; [* -|`}]&]
[s7;* &]
[s7; [* -|virtual void MouseMove(Point pos, dword flags) `{]&]
[s7; [* -|-|text `= Format(`"`[%d:%d`]`", pos.x, pos.y);]&]
[s7; [* -|-|Refresh();]&]
[s7; [* -|`}]&]
[s7; &]
[s7; -|virtual void Paint(Draw`& w) `{&]
[s7; -|-|w.DrawRect(GetSize(), SWhite);&]
[s7; -|-|w.DrawText(p.x, p.y, text, Arial(20), Magenta);&]
[s7; -|`}&]
[s7; &]
[s7; -|MyAppWindow() `{&]
[s7; -|-|Title(`"My application`").Zoomable().Sizeable();&]
[s7; -|-|p.x `= p.y `= 0;&]
[s7; -|`}&]
[s7; `};&]
[s7; &]
[s7; GUI`_APP`_MAIN&]
[s7; `{&]
[s7; -|MyAppWindow app;&]
[s7; -|app.Run();&]
[s7; `}&]
[s5; &]
[s0;= 
@@rawimage:2612&1625
([encoded data, 7080 characters])
&]
[s5; &]
[s3;:6: 6. Multiple main windows&]
[s5; If you application uses multiple top`-level peer windows, you 
cannot use the [* Run] method as it runs the modal loop for the 
window. Instead, you have to allocate top`-level windows on the 
heap and use [* Ctrl`::EventLoop] `- this event loop runs as long 
as there are any top`-level windows opened. Use `"[* delete this]`" 
in overridden [* Close] method to close and deallocate the main 
window.&]
[s5; &]
[s7; #include <CtrlLib/CtrlLib.h>&]
[s7; &]
[s7; using namespace Upp;&]
[s7; &]
[s7; struct MyAppWindow : TopWindow `{&]
[s7; -|virtual void Close() `{&]
[s7; -|-|delete this;&]
[s7; -|`}&]
[s7; &]
[s7; -|virtual void LeftDown(Point pos, dword flags) `{&]
[s7; [* -|-|(new MyAppWindow)`->OpenMain();]&]
[s7; -|`}&]
[s7; &]
[s7; -|virtual void Paint(Draw`& w) `{&]
[s7; -|-|w.DrawRect(GetSize(), SWhite);&]
[s7; -|-|w.DrawText(0, 0, `"Click the view area to open next window!`", 
Arial(20));&]
[s7; -|`}&]
[s7; &]
[s7; -|MyAppWindow() `{&]
[s7; -|-|Title(`"My multiwindowed application`").Zoomable().Sizeable();&]
[s7; -|`}&]
[s7; `};&]
[s7; &]
[s7; GUI`_APP`_MAIN&]
[s7; `{&]
[s7; [* -|(new MyAppWindow)`->OpenMain();]&]
[s7; [* -|Ctrl`::EventLoop();]&]
[s7; `}&]
[s5; &]
[s0;= 
@@rawimage:2000&1447
([encoded data, 286612 characters])
&]
[s5; &]
[s3;:7: 7. Menu&]
[s5; Content of menu in U`+`+ is represented by the function or method 
adding required menu items to the [* Bar]. Items can contain [^topic`:`/`/Core`/src`/Callbacks`$en`-us^ E
vents] to actions invoked by choosing the menu item or [^topic`:`/`/Core`/src`/Function`$en`-us`#Upp`:`:Event`:`:typedef^ E
vents] to represent sub`-menus. Menu itself is managed by [* MenuBar]. 
[* MenuBar] can act both as widget or as a [*/^topic`:`/`/CtrlCore`/srcdoc`/AboutFrames`$en`-us^ F
rame]. Frames are placed to the window border and reduce its 
view area.&]
[s5; &]
[s7; #include <CtrlLib/CtrlLib.h>&]
[s7; &]
[s7; using namespace Upp;&]
[s7; &]
[s7; struct MyAppWindow : TopWindow `{&]
[s7; -|MenuBar menu;&]
[s7; &]
[s7; -|void [* Exit]() `{&]
[s7; -|-|if(PromptOKCancel(`"Exit MyApp?`"))&]
[s7; -|-|-|Break();&]
[s7; -|`}&]
[s7; &]
[s7; -|void [* SubMenu](Bar`& bar) `{&]
[s7; -|-|bar.[* Add](`"Exit`", `[`=`] `{ [* Exit](); `});&]
[s7; -|`}&]
[s7; &]
[s7; -|void [* MainMenu](Bar`& bar) `{&]
[s7; -|-|bar.[* Sub](`"Menu`", `[`=`](Bar`& bar) `{ [* SubMenu](bar); `});&]
[s7; -|`}&]
[s7; &]
[s7; -|typedef MyAppWindow CLASSNAME;&]
[s7; &]
[s7; -|MyAppWindow() `{&]
[s7; -|-|Title(`"My application with menu`").Sizeable();&]
[s7; -|-|[* AddFrame](menu);&]
[s7; -|-|menu.[* Set](`[`=`](Bar`& bar) `{ [* MainMenu](bar); `});&]
[s7; -|`}&]
[s7; `};&]
[s7; &]
[s7; GUI`_APP`_MAIN&]
[s7; `{&]
[s7; -|MyAppWindow app;&]
[s7; -|app.Run();&]
[s7; `}&]
[s7; &]
[s5; &]
[s0;= 
@@rawimage:1434&1333
([encoded data, 4312 characters])
                 
@@rawimage:1434&1332
([encoded data, 17412 characters])
&]
[s5; Of course, with power of C`+`+11 lambdas, it is also possible, 
if not always advisable, to `'inline`' the whole menu structure 
to single MenuBar`::Set call:&]
[s7; &]
[s7; #include <CtrlLib/CtrlLib.h>&]
[s7; &]
[s7; using namespace Upp;&]
[s7; &]
[s7; struct MyAppWindow : TopWindow `{&]
[s7; -|MenuBar menu;&]
[s7; &]
[s7; -|MyAppWindow() `{&]
[s7; -|-|Title(`"My application with menu`").Sizeable();&]
[s7; -|-|AddFrame(menu);&]
[s7; -|-|menu.[* Set](`[`=`](Bar`& bar) `{&]
[s7; -|-|-|bar.Sub(`"Menu`", `[`=`](Bar`& bar) `{&]
[s7; -|-|-|-|bar.Add(`"Exit`", `[`=`] `{&]
[s7; -|-|-|-|-|if(PromptOKCancel(`"Exit MyApp?`"))&]
[s7; -|-|-|-|-|-|Break();&]
[s7; -|-|-|-|`});&]
[s7; -|-|-|`});&]
[s7; -|-|`});&]
[s7; -|`}&]
[s7; `};&]
[s7; &]
[s7; GUI`_APP`_MAIN&]
[s7; `{&]
[s7; -|MyAppWindow app;&]
[s7; -|app.Run();&]
[s7; `}&]
[s7; &]
[s5; &]
[s3;:8: 8. Context menu&]
[s5; Context local menu (usually invoked by right mouse click) is 
similar to the standard menu bar handling, just instead of adding 
MenuBar to your application, you [/ execute] the callback to the 
menu:&]
[s5; &]
[s7; #include <CtrlLib/CtrlLib.h>&]
[s7; &]
[s7; using namespace Upp;&]
[s7; &]
[s7; struct MyAppWindow : TopWindow `{&]
[s7; -|void Exit() `{&]
[s7; -|-|if(PromptOKCancel(`"Exit MyApp?`"))&]
[s7; -|-|-|Break();&]
[s7; -|`}&]
[s7; &]
[s7; -|void RightDown(Point, dword) `{&]
[s7; -|-|MenuBar`::Execute(&]
[s7; -|-|-|`[`=`](Bar`& bar) `{&]
[s7; -|-|-|-|bar.Add(`"Exit`", `[`=`] `{ Exit(); `});&]
[s7; -|-|-|`}&]
[s7; -|-|);&]
[s7; -|`}&]
[s7; &]
[s7; -|MyAppWindow() `{&]
[s7; -|-|Title(`"My application with local menu`").Sizeable();&]
[s7; -|`}&]
[s7; `};&]
[s7; &]
[s7; GUI`_APP`_MAIN&]
[s7; `{&]
[s7; -|MyAppWindow app;&]
[s7; -|app.Run();&]
[s7; `}&]
[s7; &]
[s7; &]
[s0;= 
@@rawimage:1710&1225
(iVBORw0KGgoAAAANSUhEUgAAAeQAAAFdCAIAAABdCYkTAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAASdEVYdFNvZnR3YXJlAEdyZWVuc2hvdF5VCAUAAArgSURBVHhe7d0/bxv3AcZxLkUDT9q82ICbKR3iRUuQN+DZGrM1g7cMhtcA3QwhS2LNGWp1EhDA3vUGPGgzoDcgARYg2OqUub/j70ge/0iiziStJ/p88MBgTscjT0W+puUCGfzr/e9mZnbL18T6n0f/NjOzWzuxNjMLmFibmQVMrM3MAibWZmYBE2szs4CJtZlZwMTazCxgYm1mFjCxNjPb0AaDwT/++2zmYFk5WL40c3Bm18T6m6Mftso1dn6YOf71iweDwYP7b6YOrnDD122u/82bJ/d6vVDvJ169hZcdv9vuwfGu/uoy+/wrmNltWIny3/7+1UyvFx6c3zKxfnDv8VQphgeLNeajX542GbXua139up//rjZ5X2a21s2keclSly0V662dB/de/DQ5+Gp7sLO91nz0y9Mmo9Z9ratf9/Pf1Sbvy8zWvXGgly912VKxvv+m/Lr9sD3y0/3mg3Y9Xh4Ptl6NTi4Rf/zk687TH+40n8Abwx+ktFd79eTe8Fj9DeCqg28mD4YHm5er6ot2rz88c6T9x9ETm59dtOoT26++2K4Hu78VlZXLTp02vsjksotea/oWxrv6nQxPuOq+Zq4wesrUK5ZnDX8w1Ri/eue1mv/t2qdM3/LUe5t7FTNb02qmly912ZKx7vSrJKApcnt8+Cm7/Yn2+JyZjS8yfDCoQR+m5OqDMw+aos10sG7+5LmDnTffOdimsNzC6LeiuvFNlQf3Hrd/qig1LA8uf63RLcxfbeop8+/kZvfV+VL3FUfxHb169ynNXbTvfPaWp06bexUzW9PWGOtRo9siT443D0b/2g9PmHr6sCND45MnOZi51MKDkwdN3aYiWHbF9S974vyLdh/XdW52+Om1eVySOvUSl11hwdXGT1n4Tm54X+0J17368LIdM3/UGJ92yXXMbH2rpS6/jh/MnLBwS8e61qot19S/2PUjZ/116rmjDLXPnU1D84lyrpuzBycP5qJ23fUXP3GpWLcXrL/9lMfbD8tFpm/8sissutroKQvfyQ3vqz3nuldfcNmFp11yHTNb02YCvXyvl41183j4ca/943b3eBOy7a1hVuqz6prza+CacDRfHT5rdIVJki47OH5KfdB0vPv7wSXXb9/G9BWaLC68fvfMetm65veezg9AtnaanySUx9OXXXCF+atNP2X+ndzsvtpzLnnFmdeauuzi05pXb99S879ve4KZrWML07xkr28S6/oZc+54WfmQOP7J9Xg1BI1RyuuztnbavwprG3H5wfFTRm+gPG6V0+avX85p3klx6V8wdi+14PF441DOPu6cvPi15q429dW5dzI6obXwvq655mWPJ6911ZusvwcPz1nv/8PHzMq/ZwujXA6WL80cnNk1sV5y9U/0Mwfn123E1QfNzKy7FcS6+QQ3/GP7zPH5ibWZWb99VqxHf2BfNrVibWbWbyv4ZG1mZuueWJuZBUyszcwCJtZmZgETazOzgIm1mVnAxNrMLGBibWYWsDbW/wPgFhNrgABiDRBArAECiDVAALEGCCDWAAHEGiCAWAMEEGuAAGINEECsAQKINUAAsQYIINYAAcQaIIBYAwQQa4AAYg0QQKwBAog1QACxBggg1gABxBoggFgDBBBrgABiDRBArAECiDVAALEGCCDWAAHEGiCAWAMEEGuAAGINEECsAQKINUAAsQYIINYAAcQaIIBYAwQQa4AAYg0QQKwBAog1QACxBggg1gABxBoggFgDBBBrgABiDRBArAECiDVAALEGCCDWAAHEGiCAWAMEEGuAAGINEECsAQKINUAAsQYIINYAAcQaIIBYAwQQa4AAYg0QQKwBAog1QACxBggg1gABxBoggFgDBBBrgABiDRBArAECiDVAALEGCCDWAAHEGiCAWAMEEGuAAGINEECsAQKINUAAsQYIINYAAcQaIIBYAwQQa4AAYg0QQKwBAog1QACxBggg1gABxBoggFgDBBBrgABiDRBArAECiDVAALEGCCDWAAHEGiCAWAMEEGuAAGINEECsAQKINUAAsQYIINYAAcQaIIBYAwQQa4AAYg0QQKwBAog1QACxBggg1gABxBoggFgDBBBrgABiDRBArAECiDVAALEGCCDWAAHEGiCAWAMEEGuAAGINEECs+/gPI+13BFgzse5DpCrfB9gYse5DpCrfB9gYse5jHKnf3v15N1dvX6xhY8S6D7Guty/WsDFi3YdY19sv34fT09Ozs7Pz8/NPnz5dXFzU48DKiXUfYl1vv3wfjo6Ojo+PT05OSq/FGtZHrPsQ63r75ftwcHBweHhYev3hw4fy4boeB1ZOrPsQ63r75fuwt7dXel0+X5+enoo1rI9Y9/FFY/32+8HE97/OfPXP3/745dHgu6d/zB1f6ertl+/D7u7u/v7+u3fvTk5OPn78WI8DKyfWfXzpWC/Z4uXPvPHq7Zfvw8uXL1+/fi3WsG5i3YdY19sXa9gYse7jNsX6/dNvB4+ev28e//rj4Ntffm5PKL+OPH07Onllq7cv1rAxYt3Hl4712I/P2iPlQf21/mOt+fjB6ldvX6xhY8S6j9v0yXq48pl68peNYg1/QWLdh1jX2xdr2Bix7uOWxboc8WMQ+IsT6z6+dKwnHj1/O/4Lxp+ff9f5C8bm5GdPhyf5C0bIJ9Z9fNFY34rV2xdr2Bix7kOs6+2LNWyMWPch1vX2xRo2Rqz7EOt6+2INGyPWfYh1vX2xho0R6z7Eut6+WMPGiHUf41jfcWINGyPWfYh1JdawMWLdR4kUlVjDZoj1Cpyenh4dHR0cHOzt7e3u7pZ+3R3+s16wGWK9AmdnZ8fHx4eHhyVb+/v75ZPm3eE/mAubIdYrcH5+fnJyUoJVPmC+u2PKLZcbL7dfvgkXFxftdwRYNbFegfKJsqSqfLQ8PT0t2bpTyi2XP1iU2y/fBLGG9RHrFSiRKkqtio93TL3r+h1ovx3AGog1QACxBggg1gABxBoggFgDBBBrgABiDRBArAECiDVAALEGCCDWAAHEGiCAWAMEEGuAAGINEECsAQKINUAAsQYIINYAAcQaIIBYAwQQa4AAYg0QQKwBAog1QACxBggg1gABxBoggFgDBBBrgABiDRBArAECiDVAALEGCCDWAAHEGiCAWAMEEGuAAGINEECsAQKINUAAsQYIINYAAcQaIIBYAwQQa4AAYg0QQKwBAog1QACxBggg1gABxBoggFgDBBBrgABiDRBArAECiDVAALEGCCDWAAHEGiCAWAMEEGuAAGINEECsAQKINUAAsQYIINYAAcQaIIBYAwQQa4AAYg0QQKwBAog1QACxBggg1gABxBoggFgDBBBrgABiDRBArAECiDVAALEGCCDWAAHEGiCAWAMEEGuAAGINEECsAQKINUAAsQYIINYAAcQaIIBYAwQQa4AAYg0QQKwBAog1QACxBggg1gABxBoggFgDBBBrgABiDRBArAECiDVAALEGCCDWAAHEGiCAWAMEEGuAAGINEECsAQKINUAAsQYIINYAAcQaIIBYAwQQa4AAYg0QQKwBAog1QACxBggg1gABxBoggFgDBBBrgABiDRBArAECiDVAALEGCCDWAAHEGiCAWAMEEGuAAGINEECsAQKINUAAsQYIINYAAcQaIIBYAwQQa4AAYg0QQKwBAog1QACxBggg1gABxBoggFgDBBBrgABiDRBArAECiDVAALEGCNDG2szMbvXe//5/Q2ieZvGUBGAAAAAASUVORK5CYII=)
&]
[s5;= &]
[s3;:9: 9. Context menu alternative&]
[s5; It is also possible to create context menu by adding menu items 
directly to MenuBar. Example also demonstrates how to convert 
the menu item to same value, by using lambda capture by reference:&]
[s5; &]
[s7; #include <CtrlLib/CtrlLib.h>&]
[s7; &]
[s7; using namespace Upp;&]
[s7; &]
[s7; struct MyAppWindow : TopWindow `{&]
[s7; -|void Exit() `{&]
[s7; -|-|if(PromptOKCancel(`"Exit MyApp?`"))&]
[s7; -|-|-|Break();&]
[s7; -|`}&]
[s7; &]
[s7; -|void RightDown(Point, dword) `{&]
[s7; -|-|int [* result ]`= Null;&]
[s7; -|-|[* MenuBar menu];&]
[s7; -|-|for(int i `= 0; i < 10; i`+`+)&]
[s7; -|-|-|menu.Add(AsString(i), `[`=, [* `&result]`] `{ [* result ]`= i; 
`});&]
[s7; -|-|menu.Separator();&]
[s7; -|-|menu.Add(`"Exit`", `[`=`] `{ Exit(); `});&]
[s7; -|-|menu.[* Execute]();&]
[s7; -|-|if(!IsNull([* result]))&]
[s7; -|-|-|PromptOK(`"You have selected `" `+ AsString((int)result));&]
[s7; -|`}&]
[s7; &]
[s7; -|MyAppWindow() `{&]
[s7; -|-|Title(`"My application with context menu`").Sizeable();&]
[s7; -|`}&]
[s7; `};&]
[s7; &]
[s7; GUI`_APP`_MAIN&]
[s7; `{&]
[s7; -|MyAppWindow app;&]
[s7; -|app.Run();&]
[s7; `}&]
[s7; &]
[s7; &]
[s5; &]
[s0;= 
@@rawimage:1448&1660
([encoded data, 7180 characters])
         
@@rawimage:1448&1661
([encoded data, 18892 characters])
&]
[s5; &]
[s3;:10: 10. Adding images&]
[s5; To add some eye`-candy to the menu, you can add small raster 
images. In U`+`+, images are represented by Image values. You 
can use image designer, part of TheIDE, to design Image constants&]
[s5; &]
[s0;= 
@@rawimage:3100&1890
([encoded data, 207440 characters])
&]
[s5; &]
[s5; To get the image constants into your application you have to 
use somewhat obfuscated but thankfully short sequence of preprocessor 
commands:&]
[s5; &]
[s7; #include <CtrlLib/CtrlLib.h>&]
[s7; &]
[s7; using namespace Upp;&]
[s7; &]
[s7; [* #define IMAGECLASS TutorialImg]&]
[s7; [* #define IMAGEFILE <Gui10/images.iml>]&]
[s7; [* #include <Draw/iml.h>]&]
[s7; &]
[s7; struct MyAppWindow : TopWindow `{&]
[s7; -|MenuBar menu;&]
[s7; &]
[s7; -|void Exit() `{&]
[s7; -|-|if(PromptOKCancel(`"Exit MyApp?`"))&]
[s7; -|-|-|Break();&]
[s7; -|`}&]
[s7; &]
[s7; -|void SubMenu(Bar`& bar) `{&]
[s7; -|-|bar.Add(`"Exit`", [* TutorialImg`::Exit()], `[`=`] `{ Exit(); 
`});&]
[s7; -|`}&]
[s7; &]
[s7; -|MyAppWindow() `{&]
[s7; -|-|Title(`"My application with menu and images`").Sizeable();&]
[s7; -|-|AddFrame(menu);&]
[s7; -|-|menu.Set(`[`=`](Bar`& bar) `{&]
[s7; -|-|-|bar.Sub(`"Menu`", `[`=`](Bar`& bar) `{ SubMenu(bar); `});&]
[s7; -|-|`});&]
[s7; -|`}&]
[s7; `};&]
[s7; &]
[s7; GUI`_APP`_MAIN&]
[s7; `{&]
[s7; -|MyAppWindow app;&]
[s7; -|app.Run();&]
[s7; `}&]
[s7; &]
[s5; &]
[s5; Here [*/ Tutorial ]is the name of package where .iml file resides.&]
[s5; Image constants are represented by class methods of class defined 
as [* IMAGECLASS] ([/ TutorialImg] in this case). Image constant 
then can be added to menu as another parameter of Bar`::Add.&]
[s5; Note: [* #include <Draw/iml.h>] works only when images are to be 
used in single .cpp file, otherwise you must put `"obsuscated`" 
sequence with [* #include <Draw/iml`_header.h>] to you header and 
[* #include <Draw/iml`_source.h>] to any .cpp file.&]
[s5; &]
[s0;= 
@@rawimage:1605&720
(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)
&]
[s5; &]
[s3;:11: 11. Toolbar&]
[s5; Toolbars are in fact quite similar to menus `- they provide 
set of operations with names and Images that can be invoked by 
user. In U`+`+ you can take advantage of this similarity as toolbars 
can share the definition with menus `- if [* Bar`::Add] command 
contains the Image, it also adds toolbar button with that Image 
when used with [* ToolBar]. The text of menu item then translates 
to button tip. If you want one particular Bar item to be used 
with menu or toolbar only, you can do that by using [* AddMenu] 
or [* AddTool] instead of simple Add. Also, items without Image 
are automatically added to menus only and vice versa, items without 
text are added to toolbars only.&]
[s5; &]
[s7; #include <CtrlLib/CtrlLib.h>&]
[s7; &]
[s7; using namespace Upp;&]
[s7; &]
[s7; #define IMAGECLASS TutorialImg&]
[s7; #define IMAGEFILE <[/ Tutorial]/images.iml>&]
[s7; #include <Draw/iml.h>&]
[s7; &]
[s7; struct MyAppWindow : TopWindow `{&]
[s7; -|MenuBar menu;&]
[s7; [* -|ToolBar tool;]&]
[s7; &]
[s7; -|void MenuFn() `{&]
[s7; -|-|PromptOK(`"Fn activated!`");&]
[s7; -|`}&]
[s7; &]
[s7; -|void BarFn() `{&]
[s7; -|-|PromptOK(`"Fn2 activated!`");&]
[s7; -|`}&]
[s7; -|&]
[s7; -|void Exit() `{&]
[s7; -|-|if(PromptOKCancel(`"Exit MyApp?`"))&]
[s7; -|-|-|Break();&]
[s7; -|`}&]
[s7; &]
[s7; -|void SubBar(Bar`& bar) `{&]
[s7; -|-|bar.AddMenu(`"Function`", TutorialImg`::Fn(), THISBACK(MenuFn));&]
[s7; [* -|-|bar.Add(TutorialImg`::Fn2(), THISBACK(BarFn));]&]
[s7; [* -|-|bar.Add(`"Exit`", TutorialImg`::Exit(), THISBACK(Exit));]&]
[s7; -|`}&]
[s7; &]
[s7; -|void MainMenu(Bar`& bar) `{&]
[s7; -|-|bar.Add(`"Menu`", THISBACK(SubBar));&]
[s7; -|`}&]
[s7; &]
[s7; -|typedef MyAppWindow CLASSNAME;&]
[s7; &]
[s7; -|MyAppWindow() `{&]
[s7; -|-|Title(`"My application with bars`").Sizeable();&]
[s7; -|-|AddFrame(menu);&]
[s7; [* -|-|AddFrame(tool);]&]
[s7; -|-|menu.Set(THISBACK(MainMenu));&]
[s7; [* -|-|tool.Set(THISBACK(SubBar));]&]
[s7; -|`}&]
[s7; `};&]
[s7; &]
[s7; GUI`_APP`_MAIN&]
[s7; `{&]
[s7; -|MyAppWindow app;&]
[s7; -|app.Run();&]
[s7; `}&]
[s5; &]
[s0;= 
@@rawimage:1669&879
(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)
&]
[s5; &]
[s3;:12: 12. StatusBar and decorative Frames&]
[s5; To improve the visual aspect of the application, we will add 
some decorative Frames `- those are frames that do not represent 
any action, just draw some kind of border at given frame level. 
We will also add the [* StatusBar] and connect it to the menu and 
toolbar `- this way it will start displaying descriptions placed 
to Bar items using a Help method. Note that decorative frame 
functions ([* TopSeparatorFrame] and [* InsetFrame] here) usually 
return a reference to single global object, as there are no changing 
properties required when using them with different windows and 
widgets concurrently.&]
[s5; &]
[s7; #include <CtrlLib/CtrlLib.h>&]
[s7; &]
[s7; using namespace Upp;&]
[s7; &]
[s7; #define IMAGECLASS TutorialImg&]
[s7; #define IMAGEFILE <[/ Tutorial]/images.iml>&]
[s7; #include <Draw/iml.h>&]
[s7; &]
[s7; struct MyAppWindow : TopWindow `{&]
[s7; -|MenuBar   menu;&]
[s7; -|ToolBar   tool;&]
[s7; -|StatusBar status;&]
[s7; &]
[s7; -|void MenuFn() `{&]
[s7; -|-|PromptOK(`"Fn activated!`");&]
[s7; -|`}&]
[s7; &]
[s7; -|void BarFn() `{&]
[s7; -|-|PromptOK(`"Fn2 activated!`");&]
[s7; -|`}&]
[s7; -|&]
[s7; -|void Exit() `{&]
[s7; -|-|if(PromptOKCancel(`"Exit MyApp?`"))&]
[s7; -|-|-|Break();&]
[s7; -|`}&]
[s7; &]
[s7; -|void SubBar(Bar`& bar) `{&]
[s7; -|-|bar.AddMenu(`"Function`", TutorialImg`::Fn(), THISBACK(MenuFn))&]
[s7; [* -|-|   .Help(`"This invokes MenuFn method of tutorial example`");]&]
[s7; -|-|bar.Add(TutorialImg`::Fn2(), THISBACK(BarFn))&]
[s7; [* -|-|   .Help(`"This invokes BarFn method of tutorial example`");]&]
[s7; -|-|bar.Add(`"Exit`", TutorialImg`::Exit(), THISBACK(Exit));&]
[s7; -|`}&]
[s7; &]
[s7; -|void MainMenu(Bar`& bar) `{&]
[s7; -|-|bar.Add(`"Menu`", THISBACK(SubBar));&]
[s7; -|`}&]
[s7; &]
[s7; -|typedef MyAppWindow CLASSNAME;&]
[s7; &]
[s7; -|MyAppWindow() `{&]
[s7; -|-|Title(`"My application with bars`").Sizeable();&]
[s7; -|-|AddFrame(menu);&]
[s7; [* -|-|AddFrame(TopSeparatorFrame());]&]
[s7; -|-|AddFrame(tool);&]
[s7; [* -|-|AddFrame(status);]&]
[s7; [* -|-|AddFrame(InsetFrame());]&]
[s7; -|-|menu.Set(THISBACK(MainMenu));&]
[s7; [* -|-|menu.WhenHelp `= status;]&]
[s7; -|-|tool.Set(THISBACK(SubBar));&]
[s7; [* -|-|tool.WhenHelp `= status;]&]
[s7; -|`}&]
[s7; `};&]
[s7; &]
[s7; GUI`_APP`_MAIN&]
[s7; `{&]
[s7; -|MyAppWindow app;&]
[s7; -|app.Run();&]
[s7; `}&]
[s5; &]
[s0;= 
@@rawimage:1837&876
([encoded data, 5392 characters])
&]
[s5; &]
[s3;:13: 13. Adding child Ctrls `- widgets, reacting to widget events&]
[s5; If you need to use some predefined child Ctrl (widget), place 
as variable somewhere, usually as member variable of your window 
or dialog class and use [* Add] (or [* operator <<]) to put it to 
your window.&]
[s7; &]
[s7; #include <CtrlLib/CtrlLib.h>&]
[s7; &]
[s7; using namespace Upp;&]
[s7; &]
[s7; struct MyAppWindow : TopWindow `{&]
[s7; -|[* Button button;]&]
[s7; -|&]
[s7; -|void Click() `{ PromptOK(`"You have clicked the button!`"); 
`}&]
[s7; &]
[s7; -|typedef MyAppWindow CLASSNAME;&]
[s7; &]
[s7; -|MyAppWindow() `{&]
[s7; -|-|Title(`"My application with button`");&]
[s7; -|-|[* Add(button.LeftPos(10, 100).TopPos(10, 30));]&]
[s7; -|-|button.SetLabel(`"Click me!`");&]
[s7; -|-|[* button <<`= THISBACK(Click);]&]
[s7; -|`}&]
[s7; `};&]
[s7; &]
[s7; GUI`_APP`_MAIN&]
[s7; `{&]
[s7; -|MyAppWindow app;&]
[s7; -|app.Run();&]
[s7; `}&]
[s7; &]
[s5; Position within parent view is given in logical coordinates 
(e.g. [* LeftPos] or [* TopPos]) that allow no`-nonsense resizing 
of dialog. Widget events (like `"button pushed`") are reflected 
by its callbacks. There exists a `"default`" [* WhenAction] callback 
in each widget that is usually invoked for `"user changed a value 
or a state of widget`" situation. You can assign this callback 
either as&]
[s7; &]
[s7; widget.[* WhenAction] `= ....&]
[s7; &]
[s5; or use equivalent operator version to save some typing&]
[s7; &]
[s7; widget [* <<`=] ....&]
[s7; &]
[s5; Note also that to make the code more clear and less verbose, 
U`+`+ uses `"method chaining`" technique, where methods (usually 
those that affect appearance, position or behaviour of widgets 
`- `"modifiers`" in U`+`+ lingo) are designed to return a reference 
to `*this `- that should explain the line&]
[s5; &]
[s7; Add(button.LeftPos(10, 100).TopPos(10, 30));&]
[s5; &]
[s0;= 
@@rawimage:1724&1324
([encoded data, 13240 characters])
&]
[s5; &]
[s3;:14: 14. More about logical coordinates&]
[s5; Logical coordinates can align one or both sides of widget to 
the side of parent view at specified distance(s) in both vertical 
and horizontal direction. If only one side is aligned, logical 
coordinate specifies the size. There is also specific kind of 
logical coordinate the specifies the center position.&]
[s5; &]
[s7; #include <CtrlLib/CtrlLib.h>&]
[s7; &]
[s7; using namespace Upp;&]
[s7; &]
[s7; struct MyAppWindow : TopWindow `{&]
[s7; -|Button lt, rt, lb, rb, lv, ht, hv, cb, rc;&]
[s7; &]
[s7; -|typedef MyAppWindow CLASSNAME;&]
[s7; &]
[s7; -|MyAppWindow() `{&]
[s7; -|-|Title(`"My application with button`").Sizeable();&]
[s7; -|-|`*this&]
[s7; [* -|-|-|<< lt.SetLabel(`"left`-top`").LeftPos(10, 100).TopPos(10, 
20)]&]
[s7; [* -|-|-|<< rt.SetLabel(`"right`-top`").RightPos(10, 100).TopPos(10, 
20)]&]
[s7; [* -|-|-|<< lb.SetLabel(`"left`-bottom`").LeftPos(10, 100).BottomPos(10, 
20)]&]
[s7; [* -|-|-|<< rb.SetLabel(`"right`-bottom`").RightPos(10, 100).BottomPos(10, 
20)]&]
[s7; [* -|-|-|<< lv.SetLabel(`"left`-vsize`").LeftPos(10, 100).VSizePos(40, 
40)]&]
[s7; [* -|-|-|<< ht.SetLabel(`"hsize`-pos`").HSizePos(120, 120).TopPos(10, 
20)]&]
[s7; [* -|-|-|<< hv.SetLabel(`"hsize`-vsize`").HSizePos(120, 120).VSizePos(40, 
40)]&]
[s7; [* -|-|-|<< cb.SetLabel(`"hcenter`-bottom`").HCenterPos(90).BottomPos(10, 
20)]&]
[s7; [* -|-|-|<< rc.SetLabel(`"right`-vcenter`").RightPos(10, 100).VCenterPos(40)]&]
[s7; -|-|;&]
[s7; -|`}&]
[s7; `};&]
[s7; &]
[s7; GUI`_APP`_MAIN&]
[s7; `{&]
[s7; -|MyAppWindow app;&]
[s7; -|app.Run();&]
[s7; `}&]
[s7; &]
[s5; &]
[s0;= 
@@rawimage:2000&923
([encoded data, 6876 characters])
&]
[s0;= &]
[s0;= 
@@rawimage:1495&1546
([encoded data, 7112 characters])
&]
[s5; &]
[s3;:15: 15. Font`-zoomed logical coordinates&]
[s5; All distances in U`+`+ widgets are always in pixels. However, 
to respond to platform setting of GUI font, there are `"font`-zoomed`" 
logical coordinates. Such coordinates scale distances by the 
ratio of current standard GUI font size to design font size (which 
is fixed to the default Windows font):&]
[s5; &]
[s7; #include <CtrlLib/CtrlLib.h>&]
[s7; &]
[s7; using namespace Upp;&]
[s7; &]
[s7; struct MyAppWindow : TopWindow `{&]
[s7; -|Button button;&]
[s7; &]
[s7; -|typedef MyAppWindow CLASSNAME;&]
[s7; &]
[s7; -|MyAppWindow() `{&]
[s7; -|-|Title(`"My application with font`-zoomed button`").Sizeable();&]
[s7; -|-|`*this << button.SetLabel(`"Button`").[* LeftPos][*@6 Z](10, 64).[* TopPos][*@6 Z](10,
 24);&]
[s7; -|`}&]
[s7; `};&]
[s7; &]
[s7; GUI`_APP`_MAIN&]
[s7; `{&]
[s7; -|MyAppWindow app;&]
[s7; -|app.Run();&]
[s7; `}&]
[s5; &]
[s0;= 
@@image:1640&509
([encoded data, 7396 characters])
       
@@image:1749&524
([encoded data, 8040 characters])
&]
[s5; &]
[s3;:16: 16. Layouts&]
[s5; Placing widgets by specifying their numeric logical coordinates 
is time consuming, therefore TheIDE provides visual designer 
to simplify this task.&]
[s5; &]
[s0;= 
@@rawimage:3502&2261
([encoded data, 30620 characters])
&]
[s5; &]
[s5; Visual design in U`+`+ is called `"layout`" and group of layouts 
is stored in .lay file. Format of .lay files is such that it 
can be directly included into C`+`+:&]
[s5; &]
[s7; #include <CtrlLib/CtrlLib.h>&]
[s7; &]
[s7; using namespace Upp;&]
[s7; &]
[s7; [* #define LAYOUTFILE <Gui16/dlg.lay>]&]
[s7; [* #include <CtrlCore/lay.h>]&]
[s7; &]
[s7; struct MyApp : public WithDlgLayout<TopWindow> `{&]
[s7; -|MyApp() `{&]
[s7; -|-|[* CtrlLayout(`*this, `"My dialog`");]&]
[s7; -|`}&]
[s7; `};&]
[s7; &]
[s7; GUI`_APP`_MAIN&]
[s7; `{&]
[s7; -|MyApp().Run();&]
[s7; `}&]
[s5; &]
[s0;= 
@@rawimage:1235&551
(iVBORw0KGgoAAAANSUhEUgAAAOAAAABkCAIAAAAQbqt4AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAASdEVYdFNvZnR3YXJlAEdyZWVuc2hvdF5VCAUAAASiSURBVHhe7Zw/TtxAFIfdRImo6KgogihIQxOJljvQUUTaKyCaVGmh5QJpIqXZggtwBESba+QGybz55/HYu+NFDH5rf59+Wo3fPHul1adnIxaab0+/CVEbEfTL809CFAZBieogKFEdBCWqg6BEdRCUqA6CEtXJBT17vjlsmubqJlZcTm5Pm+b06LFTdPGnBA5u73398fpg2ynDW2R+MVZ8/vUjK5qYotnKilkGBT09OO/YExQs2+Y7e35nQdBFxYj44eOnzNHBYj/Dgh5encZBKMWHy+bqcpNSmW12cF4ed3uyIOjSkuk40k6TYUGPHs2rl+zs+f5IBqqrm3Vz+BCajbjn1yeZoNIvPamFx1cygQU7XNMtK7SnvXIoHtxepxcn+5so5Xg7TTYJKko5XcSVxEI7Tf0d3PVk43BQ0LAVLtJZJG/UK2559iV7F6fmeDtNNgoavMwttAsZrrKwDXErXMFN3E5dtPZ0tqyU7fOAf6/w1vZqnYuTvc6bCuo8e/CupKKYqWaeUN1reoq/QnCub2HfXQRdTpyd5jUusobBbBRU1nbs9S20Al0ehp/0O1uyDrfsUA+Pqk5HW4lbaX/rcVvkFj+PZFKOd3SroDLw/HhL6yZm1MUnUedToO2Jp7inUiFo3XkX8dKRnBseCfghaQYZ1HGko7mgI+PuxVmxRuJYzepkj2IGzaCIpmi2smKW1whqb/H+GbF2ZFS/13sRhdlN0HCzrnvPbR8JBMbnovOaCUrIuwVBieogKFEdBCWqg6BEdRCUqI4X9C+AShAUVIOgoBoEBdUgKKgGQUE1CAqqQVBQDYKCarQL2nz/Q4rxH9Yc2QNB/8FWEHRKELQIgk5JKmjTNH4FCQg6JQhaBEGnBEGLLFzQ9aq5uHvxBxsY02MY2dYBQYsgKIKqBkERVDUImltlSp7VOhQu7tZ3F7bWdr/4SuhD0Cog6Car4pY11i1FylgMJ65XdoWgVUDQnlVWSEvPRXsgA7MdnxYpIWgVELRrlZjnbtlm1Rc0bLdtEQStAoJ2rYoFUTAKGppaL5OiB0GrgKAt1i9x0B6sVskENQe2mozN0ChIFUGrsHBBJwZBiyDolCBoEQSdEgQtgqBTkgoKgyDolCBoEQSdEvPpk2L8hzVHtAsKCwdBQTUICqpBUFANgoJqEBRUg6CgGgQF1RQE/ToO3w3w1pQF9b9Q2wyCQj2qCZp80XmHbym339IHEOoIKnZGz4rSveab9rAQagja/l2Sp1fogqCwkQqCDuhoSk5B62LnXzwkjwLZ3y3JdTzhcnb3zp+B1EugjqC5O9FZq6PblZpbJVK2a+n0XnY6QzXZhxkzxQT1LspBsLYnaPci2zph1lQQtG9oW0ititUh7RAULDUEtfK0eslBUClZD1sb18klCp0wZ+oIahDBPFFVZ1X/Xzz4XjlOtBMvHYNSpmuYLdUEHQarYDfKgo7Bd5dBUNiNgqBvDYLCbryzoAC7gaCgGgQF1SAoqAZBQTUICqpBUFANgoJqEBRUg6CgGgQF1SAoqAZBQTUICqpBUFANgoJqEBRUg6CgGgQF1SAoqAZBQTVeUEKU5un3f/yTFC35jMdxAAAAAElFTkSuQmCC)
&]
[s5; &]
[s5; To understand how this works, let us examine content of .lay 
file first:&]
[s5; &]
[s7; LAYOUT([* DlgLayout], [* 208], [* 64])&]
[s7; -|ITEM([* Label], [* dv`_`_`_0], [* SetLabel(t`_(`"Label`")).LeftPosZ(8, 
36).TopPosZ(8, 19)])&]
[s7; -|ITEM([* EditString], [* text], [* LeftPosZ(48, 92).TopPosZ(8, 19)])&]
[s7; -|ITEM([* Option], [* option], [* SetLabel(t`_(`"Option`")).LeftPosZ(8, 
108).TopPosZ(32, 15)])&]
[s7; END`_LAYOUT&]
[s5; &]
[s5; Header [* CtrlCore/lay.h] includes [* LAYOUTFILE] several times, 
altering definition of LAYOUT, ITEM and END`_LAYOUT to produce 
C`+`+ code which simplified form for this example looks like&]
[s5; &]
[s7; template <class T> struct With[* DlgLayout] `{&]
[s7; -|[* Label] [* dv`_`_`_0];&]
[s7; -|[* EditString] [* text];&]
[s7; -|[* Option] [* option];&]
[s7; `};&]
[s7; &]
[s7; template <class T>&]
[s7; CtrlLayout(With[* DlgLayout]<T>`& dlg, const char `*title)&]
[s7; `{&]
[s7; -|Size sz `= Ctrl`::LayoutZoom([* 208], [* 64])&]
[s7; -|dlg.SetMinSize(sz);&]
[s7; -|dlg.SetRect(sz);&]
[s7; -|dlg.Title(title);&]
[s7; -|[* dv`_`_`_0].[* SetLabel(t`_(`"Label`")).LeftPosZ(8, 36).TopPosZ(8, 
19)];&]
[s7; -|[* text].[* LeftPosZ(48, 92).TopPosZ(8, 19)];&]
[s7; -|[* option].[* SetLabel(t`_(`"Option`")).LeftPosZ(8, 108).TopPosZ(32, 
15)];&]
[s7; `}&]
[s5; &]
[s5; This way, U`+`+ keeps tight coupling between visual design and 
C`+`+ code.&]
[s5; [/ Notes: ][*/ t`_][/  function with string literal argument provides 
internationalization of texts. ][*/ dv`_`_`_0][/  is synthetic member 
variable name used for unnamed layout members (0 is index of 
member).]&]
[s5; &]
[s3;:17: 17. Value of widget&]
[s5; Many widgets have some sort of natural value. E.g. the value 
of [^`:`:EditString^ EditString] is String entered by user, whereas 
the value of [^`:`:Option^ Option] is bool specifying the status 
of the option.&]
[s5; U`+`+ provides unified interface to determine the main value 
of widget via [* GetData] and [* SetData] methods. All types of values 
are passed using polymorphic Value.&]
[s5; &]
[s7; #include <CtrlLib/CtrlLib.h>&]
[s7; &]
[s7; using namespace Upp;&]
[s7; &]
[s7; GUI`_APP`_MAIN&]
[s7; `{&]
[s7; -|TopWindow  app;&]
[s7; -|app.SetRect(0, 0, 200, 20);&]
[s7; -|EditString text;&]
[s7; -|app.Add(text.TopPosZ(0, 20).HSizePos());&]
[s7; &]
[s7; -|text.[* SetData](`"Some text`");&]
[s7; -|app.Run();&]
[s7; -|PromptOK((String)text.[* GetData]());&]
[s7; `}&]
[s5; &]
[s5; Because this feature is used very frequently, U`+`+ provides 
operator overloads for this interface `- [* operator<<`=] for SetData 
and [* operator`~] for GetData.&]
[s5; &]
[s7; #include <CtrlLib/CtrlLib.h>&]
[s7; &]
[s7; using namespace Upp;&]
[s7; &]
[s7; GUI`_APP`_MAIN&]
[s7; `{&]
[s7; -|TopWindow  app;&]
[s7; -|app.SetRect(0, 0, 200, 20);&]
[s7; -|EditString text;&]
[s7; -|app.Add(text.TopPosZ(0, 20).HSizePos());&]
[s7; &]
[s7; -|text [* <<`=] `"Some text `- operator version`";&]
[s7; -|app.Run();&]
[s7; -|PromptOK((String)[* `~]text);&]
[s7; `}&]
[s5; &]
[s3;:18: 18. Accepting and rejecting widgets&]
[s5; Ctrl interface provides&]
[s5; &]
[s7; -|virtual bool   [* Accept]();&]
[s7; -|virtual void   [* Reject]();&]
[s5; &]
[s5; methods. [*/ Accepting] is usually a reaction to pressing OK button 
or similar approve operation and usually involves testing for 
correct content and finishing any pending operations for widget 
(this may involve e.g. updating data to SQL database). Accept 
must return [* true] if widget is accepted.&]
[s5; Default Ctrl implementation calls GetData for the widget. If 
ErrorValue (special Value content) is returned by GetData, displays 
error information contained and returns false, otherwise recursively 
calls Accept for all children, anding the loop and returning 
false when any child returns one. If no false was returned so 
far, Accept returns true.&]
[s5; The opposite method to Accept is [*/ Reject]. This is used when 
Cancel button is pressed or similar rejecting action. It simply 
cancels all pending operations on widget. Default implementation 
calls Reject for all children.&]
[s5; &]
[s7; #include <CtrlLib/CtrlLib.h>&]
[s7; &]
[s7; using namespace Upp;&]
[s7; &]
[s7; GUI`_APP`_MAIN&]
[s7; `{&]
[s7; -|TopWindow  app;&]
[s7; -|app.SetRect(0, 0, 200, 20);&]
[s7; -|EditDate  date;&]
[s7; -|app.Add(date.TopPosZ(0, 20).HSizePos());&]
[s7; -|app.Run();&]
[s7; -|if(app.[* Accept]())&]
[s7; -|-|PromptOK(`"Correct date.`&`[`* `" `+ AsString(`~date));&]
[s7; `}&]
[s5; &]
[s0;= 
@@image:1029&260
([encoded data, 4148 characters])
 
@@image:854&629
([encoded data, 7864 characters])
&]
[s5;= &]
[s0;= 
@@image:1029&260
(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)
 
@@image:874&629
([encoded data, 8848 characters])
&]
[s5;= &]
[s3;:19: 19. Widget edit status flags&]
[s5; Ctrl interface provides several edit status flags:&]
[s5;l160;i150;O0; [*/ Enabled]/[*/ Disabled] `- disabled widgets do not 
receive any input. Disabled status is usually expressed by altered 
visual appearance of widget.&]
[s5;l160;i150;O0; [*/ Editable]/[*/ ReadOnly] `- read only widgets receive 
input messages but no changes to data are allowed. The difference 
from disabled status is that ReadOnly status allows read operations, 
like selecting and copying data to clipboard.&]
[s5;l160;i150;O0; [*/ Modified] `- modify flag is set to true whenever 
data in widget change `- either by user action or by widget`'s 
interface. Flag is cleared by [* ClearModify] method.&]
[s5; Note that with exception of suppressing input events for disabled 
state, implementation of widgets is responsible for correct behaviour 
with respect to listed flags.&]
[s5; &]
[s7; #include <CtrlLib/CtrlLib.h>&]
[s7; &]
[s7; using namespace Upp;&]
[s7; &]
[s7; GUI`_APP`_MAIN&]
[s7; `{&]
[s7; -|TopWindow  app;&]
[s7; -|app.SetRect(0, 0, 200, 60);&]
[s7; -|EditDate  date1, date2, date3;&]
[s7; -|date1 <<`= date2 <<`= date3 <<`= GetSysDate();&]
[s7; -|date1.[* ClearModify]();&]
[s7; -|app.Add(date1.TopPosZ(0, 20).HSizePos());&]
[s7; -|date2.[* Disable]();&]
[s7; -|app.Add(date2.TopPosZ(20, 20).HSizePos());&]
[s7; -|date3.[* SetReadOnly]();&]
[s7; -|app.Add(date3.TopPosZ(40, 20).HSizePos());&]
[s7; -|app.Run();&]
[s7; -|if(date1.[* IsModified]())&]
[s7; -|-|PromptOK(`"Date was modified!`");&]
[s7; `}&]
[s5; &]
[s0;= 
@@image:1029&460
([encoded data, 4856 characters])
 
@@image:994&629
([encoded data, 8804 characters])
&]
[s5; &]
[s3;:20: 20. Breaking the modal loop&]
[s5; When you invoke [* Run] for your TopWindow,  the new event loop 
is entered. In order to exit it, e.g. by pressing the button, 
you have to call TopWindow`'s [* Break] method. Argument passed 
to Break is then returned from Run.&]
[s5; &]
[s7; #include <CtrlLib/CtrlLib.h>&]
[s7; &]
[s7; using namespace Upp;&]
[s7; &]
[s7; struct MyApp : TopWindow `{&]
[s7; -|Button exit;&]
[s7; &]
[s7; -|void Exit() `{&]
[s7; -|-|[* Break](999);&]
[s7; -|`}&]
[s7; -|&]
[s7; -|typedef MyApp CLASSNAME;&]
[s7; -|&]
[s7; -|MyApp() `{&]
[s7; -|-|SetRect(0, 0, 100, 100);&]
[s7; -|-|Add(exit.SetLabel(`"exit`").LeftPosZ(10, 64).TopPosZ(10, 24));&]
[s7; -|-|exit <<`= THISBACK(Exit);&]
[s7; -|`}&]
[s7; `};&]
[s7; &]
[s7; GUI`_APP`_MAIN&]
[s7; `{&]
[s7; -|MyApp().Run();&]
[s7; `}&]
[s5; &]
[s5; As this is very common situation, TopWindow provides another 
method, [* Breaker], which returns a Callback which, when invoked, 
performs the [* Break].&]
[s5; &]
[s7; #include <CtrlLib/CtrlLib.h>&]
[s7; &]
[s7; using namespace Upp;&]
[s7; &]
[s7; struct MyApp : TopWindow `{&]
[s7; -|Button exit;&]
[s7; &]
[s7; -|typedef MyApp CLASSNAME;&]
[s7; -|&]
[s7; -|MyApp() `{&]
[s7; -|-|SetRect(0, 0, 100, 100);&]
[s7; -|-|Add(exit.SetLabel(`"exit`").LeftPosZ(10, 64).TopPosZ(10, 24));&]
[s7; -|-|exit <<`= [* Breaker](999);&]
[s7; -|`}&]
[s7; `};&]
[s7; &]
[s7; GUI`_APP`_MAIN&]
[s7; `{&]
[s7; -|MyApp().Run();&]
[s7; `}&]
[s5; &]
[s5; Another common situation is handling OK and Cancel buttons. 
OK button has to Accept the dialog before breaking the loop (if 
accept is successful), Cancel has to Reject it. TopWindow therefore 
provides [* Acceptor] and [* Rejector] methods providing Callbacks 
that invoke [* Accept] and [* Reject] as needed before calling the 
[* Break].&]
[s5; &]
[s7; #include <CtrlLib/CtrlLib.h>&]
[s7; &]
[s7; using namespace Upp;&]
[s7; &]
[s7; struct MyApp : TopWindow `{&]
[s7; -|Button ok, cancel;&]
[s7; -|EditDate date;&]
[s7; &]
[s7; -|typedef MyApp CLASSNAME;&]
[s7; -|&]
[s7; -|MyApp() `{&]
[s7; -|-|SetRect(0, 0, 200, 90);&]
[s7; -|-|Add(date.LeftPosZ(10, 80).TopPosZ(10, 20));&]
[s7; -|-|Add(ok.SetLabel(`"OK`").LeftPosZ(10, 64).TopPosZ(40, 24));&]
[s7; -|-|Add(cancel.SetLabel(`"Cancel`").LeftPosZ(100, 64).TopPosZ(40, 
24));&]
[s7; &]
[s7; -|-|ok.[* Ok]() <<`= [* Acceptor]([*@(128.0.255) IDOK]);&]
[s7; -|-|cancel.[* Cancel]() <<`= [* Rejector]([*@(128.0.255) IDCANCEL]);&]
[s7; -|`}&]
[s7; `};&]
[s7; &]
[s7; GUI`_APP`_MAIN&]
[s7; `{&]
[s7; -|MyApp app;&]
[s7; -|switch(app.Run()) `{&]
[s7; -|case [*@(128.0.255) IDOK]:&]
[s7; -|-|PromptOK(String().Cat() << `"OK: `" << `~app.date);&]
[s7; -|-|break;&]
[s7; -|case [*@(128.0.255) IDCANCEL]:&]
[s7; -|-|Exclamation(`"Canceled`");&]
[s7; -|`}&]
[s7; `}&]
[s5; &]
[s5; Calls to [* Ok] and [* Cancel] methods of Button here make Button 
react to Enter and Esc keys.&]
[s5; &]
[s5; To reduce tedious tasks even further, there are CtrlLayoutOK, 
CtrlLayoutCancel, CtrlLayoutOKCancel etc. template functions 
that both setup layout and assign Acceptors and Rejectors.&]
[s5; &]
[s7; #include <CtrlLib/CtrlLib.h>&]
[s7; &]
[s7; using namespace Upp;&]
[s7; &]
[s7; #define LAYOUTFILE <Gui20d/myapp.lay>&]
[s7; #include <CtrlCore/lay.h>&]
[s7; &]
[s7; GUI`_APP`_MAIN&]
[s7; `{&]
[s7; -|WithMyAppLayout<TopWindow> app;&]
[s7; -|[* CtrlLayoutOKCancel](app, `"MyApp`");&]
[s7; -|switch(app.Run()) `{&]
[s7; -|case IDOK:&]
[s7; -|-|PromptOK(String().Cat() << `"OK: `" << `~app.date);&]
[s7; -|-|break;&]
[s7; -|case IDCANCEL:&]
[s7; -|-|Exclamation(`"Canceled`");&]
[s7; -|`}&]
[s7; `}&]
[s5; &]
[s5; Note: IDOK, IDCANCEL are predefined constants.&]
[s3;:21: 21. Creating and using custom widgets&]
[s5; There is really nothing special about creating your own widgets. 
All that is to be done is to derive your own class from Ctrl 
(or some other existing widget, if that fits better) and override 
Ctrl`'s virtual methods to paint the widgets and do something 
useful:&]
[s5; &]
[s7; struct MyCtrl : public Ctrl `{&]
[s7; -|int count;&]
[s7; -|&]
[s7; -|virtual void Paint(Draw`& w) `{&]
[s7; -|-|w.DrawRect(GetSize(), White());&]
[s7; -|-|w.DrawText(2, 2, AsString(count));&]
[s7; -|`}&]
[s7; -|&]
[s7; -|virtual void LeftDown(Point, dword) `{&]
[s7; -|-|count`+`+;&]
[s7; -|-|Refresh();&]
[s7; -|`}&]
[s7; -|&]
[s7; -|MyCtrl() `{ count `= 0; `}&]
[s7; `};&]
[s5; &]
[s5; To put your widget into your layout based dialog, the simple 
way is to add it as `"User class`". In that case you just fill 
in the name of class and layout designer shows the custom widget 
as empty rectangle with class name sticked on it:&]
[s5; &]
[s0;= 
@@image:2374&1454
([encoded data, 11640 characters])
&]
[s5; &]
[s5; Note that layout file has to be included [* after] declaration 
of custom widget (so that the class is defined at that point).&]
[s5; While empty rectangle in layout designer is usually enough for 
seldom used widgets, you can also teach TheIDE to show something 
better using .usc script file:&]
[s5; &]
[s7; ctrl MyCtrl `{&]
[s7; -|group `"Example`";&]
[s7; &]
[s7; -|GetMinSize() `{ sz `= GetTextSize(`"X`"); sz.cy `+`= 2; return 
sz; `}&]
[s7; -|GetStdSize() `{ sz `= GetMinSize(); sz.cx `*`= 7; return sz; 
`}&]
[s7; &]
[s7; -|Paint(w) `{&]
[s7; -|-|r `= GetRect();&]
[s7; -|-|w.DrawRect(r, :White);&]
[s7; -|-|w.DrawText(2, 2, `"0`", StdFont(), :Black);&]
[s7; -|`}&]
[s7; `};&]
[s5; &]
[s5; [/ Note: This is not the C`+`+, but a piece of script in `"Esc`" 
scripting language, interpreted by layout designer.]&]
[s5;/ &]
[s0;= 
@@image:1120&600
(A+AAeAAAAAAAAAAAAHic7d0xTsMAEEXB3P9U3CykQUIRBWvLy8OaUQ4Q73+VGz+fAAAA/OwBFzvZ5wdcRp+U6ZMyfVKmT8r0SZk+KdMnZfqkTJ+U6ZMyfVKmT8r0SZk+KdMnZfqkTJ+U6ZMyfVKmT8r0SZk+KdMnZfqkTJ+U6ZMyfVKmT8r0SZk+KdMnZfqkTJ+U6ZMyfVJ2jz7PPAIjy8vqk5HlZfXJyPKy+mRkeVl9MrK87M36fHw5vQM/W172Tn1+fxaJXmR5WX0ysrysPhlZXlafjCwvq09GlpfVJyPLy75mfPuNpPp8er90veVlb9YnV1teVp+MLC+rT0aWl9UnI8vL6pOR5WXv9H6JBcvL6pOR5WX1ycjysvpkZHlZfTKyvKw+GVleVp+MLC+rT0aWl9UnI8vL6pOR5WXv0Sd3pU/K9EmZPinTJ2X6pEyflOmTMn1Spk/K9EmZPinTJ2X6pEyflOmTMn1Spk/K9EmZPinTJ2X6pEyflOmTMn1Spk/K9EmZPinTJ2X6pEyflOmTMn1Spk/K9EmZPik73ye/8/4d87/+P//Fqe+/80vufIy77XDnY9xthzsf42473PkYd9vhzse4GwAAAADAyydQulkb)
&]
[s5; &]
[s3;:22: 22. Non`-modal dialogs&]
[s5; To have non`-modal dialog, just open [* Open] it passing its owner 
window as parameter. Usually the best arrangement is to have 
non`-modal dialog as member variable of its owner window. Non`-modal 
dialog is dismissed using the [* Close] method just like any other 
window.&]
[s5; &]
[s7; #include <CtrlLib/CtrlLib.h>&]
[s7; &]
[s7; using namespace Upp;&]
[s7; &]
[s7; struct NonModalDialog : public TopWindow `{&]
[s7; -|Button b;&]
[s7; -|&]
[s7; -|void DoClose() `{&]
[s7; -|-|[* Close]();&]
[s7; -|`}&]
[s7; -|&]
[s7; -|typedef NonModalDialog CLASSNAME;&]
[s7; -|&]
[s7; -|NonModalDialog() `{&]
[s7; -|-|SetRect(0, 0, 200, 50);&]
[s7; -|-|Add(b.SetLabel(`"Close non`-modal dialog`").SizePos());&]
[s7; -|-|b <<`= THISBACK(DoClose);&]
[s7; -|`}&]
[s7; `};&]
[s7; &]
[s7; struct MainWindow : public TopWindow `{&]
[s7; -|[* NonModalDialog dlg];&]
[s7; -|Button b;&]
[s7; -|&]
[s7; -|void DoOpen() `{&]
[s7; -|-|if(dlg.IsOpen())&]
[s7; -|-|-|[* dlg.Close();]&]
[s7; -|-|else&]
[s7; -|-|-|[* dlg.Open(this);]&]
[s7; -|`}&]
[s7; -|&]
[s7; -|typedef MainWindow CLASSNAME;&]
[s7; -|&]
[s7; -|MainWindow() `{&]
[s7; -|-|SetRect(0, 0, 400, 100);&]
[s7; -|-|Add(b.SetLabel(`"Open/close non`-modal dialog`").SizePos());&]
[s7; -|-|b <<`= THISBACK(DoOpen);&]
[s7; -|`}&]
[s7; `};&]
[s7; &]
[s7; GUI`_APP`_MAIN&]
[s7; `{&]
[s7; -|MainWindow win;&]
[s7; -|win.Run();&]
[s7; `}&]
[s5;/ &]
[s0;= 
@@image:2084&940
([encoded data, 10852 characters])
&]
[s5;/ &]
[s3; Recommended tutorials:&]
[s5; If you want to learn more, we have several tutorials that you 
can find useful:&]
[s5;l192;i150;O0; [^topic`:`/`/Draw`/srcdoc`/DrawTutorial`$en`-us^ Draw 
tutorial ]`- in this tutorial we show more advance techniques 
of drawing inside window. This is the natural continue of things 
mention on this page.&]
[s5;l192;i150;O0; [^topic`:`/`/Draw`/srcdoc`/ImgTutorial`$en`-us^ Image 
tutorial] `- here we move things related to images. We show how 
to create, use and embed icons directly in application.&]
[s5;l192;i150;O0; [^topic`:`/`/Core`/srcdoc`/CoreTutorial`$en`-us^ Core 
value types tutorial] `- learn basics about non user U`+`+ related 
code.]]