From 7b291a1a5d3cd6935f5c159716f60d08f75e162c Mon Sep 17 00:00:00 2001 From: Mirek Fidler Date: Fri, 6 Jun 2025 12:17:34 +0200 Subject: [PATCH] CtrlCore, reference: CustomTitleBar docs and reference example --- examples/UWord/UWord.cpp | 26 ++++---- reference/CustomTitleBar/CustomTitleBar.upp | 9 +++ reference/CustomTitleBar/main.cpp | 69 +++++++++++++++++++++ uppsrc/CtrlCore/TopWindow.cpp | 4 +- uppsrc/CtrlCore/TopWindow.h | 3 +- uppsrc/CtrlCore/src.tpp/TopWindow_en-us.tpp | 34 ++++++++++ 6 files changed, 128 insertions(+), 17 deletions(-) create mode 100644 reference/CustomTitleBar/CustomTitleBar.upp create mode 100644 reference/CustomTitleBar/main.cpp diff --git a/examples/UWord/UWord.cpp b/examples/UWord/UWord.cpp index 628e3d109..d8f085b01 100644 --- a/examples/UWord/UWord.cpp +++ b/examples/UWord/UWord.cpp @@ -60,39 +60,39 @@ public: void UWord::FileBar(Bar& bar) { - bar.Add("New", CtrlImg::new_doc(), THISBACK(New)) + bar.Add("New", CtrlImg::new_doc(), [=] { New(); }) .Key(K_CTRL_N) .Help("Open new window"); - bar.Add("Open..", CtrlImg::open(), THISBACK(Open)) + bar.Add("Open..", CtrlImg::open(), [=] { Open(); }) .Key(K_CTRL_O) .Help("Open existing document"); - bar.Add(editor.IsModified(), "Save", CtrlImg::save(), THISBACK(Save)) + bar.Add(editor.IsModified(), "Save", CtrlImg::save(), [=] { Save(); }) .Key(K_CTRL_S) .Help("Save current document"); - bar.Add("SaveAs", CtrlImg::save_as(), THISBACK(SaveAs)) + bar.Add("SaveAs", CtrlImg::save_as(), [=] { SaveAs(); }) .Help("Save current document with a new name"); bar.ToolGap(); bar.MenuSeparator(); - bar.Add("Export to PDF..", UWordImg::pdf(), THISBACK(Pdf)) + bar.Add("Export to PDF..", UWordImg::pdf(), [=] { Pdf(); }) .Help("Export document to PDF file"); if(bar.IsMenuBar()) { if(lrufile().GetCount()) - lrufile()(bar, THISBACK(OpenFile)); + lrufile()(bar, [=](const String& path) { OpenFile(path); }); bar.Separator(); - bar.Add("Exit", THISBACK(Destroy)); + bar.Add("Exit", [=] { Destroy(); }); } } void UWord::AboutMenu(Bar& bar) { - bar.Add("About..", THISBACK(About)); + bar.Add("About..", [=] { About(); }); } void UWord::MainMenu(Bar& bar) { - bar.Add("File", THISBACK(FileBar)); - bar.Add("Window", callback(WindowsMenu)); - bar.Add("Help", THISBACK(AboutMenu)); + bar.Sub("File", [=](Bar& bar) { FileBar(bar); }); + bar.Sub("Window", [=](Bar& bar) { WindowsMenu(bar); }); + bar.Sub("Help", [=](Bar& bar) { AboutMenu(bar); }); } void UWord::New() @@ -237,7 +237,7 @@ void UWord::MainBar(Bar& bar) void UWord::SetBar() { - toolbar.Set(THISBACK(MainBar)); + toolbar.Set([=](Bar& bar) { MainBar(bar); }); } UWord::UWord() @@ -251,7 +251,7 @@ UWord::UWord() AddFrame(toolbar); AddFrame(statusbar); Add(editor.SizePos()); - menubar.Set(THISBACK(MainMenu)); + menubar.Set([=](Bar& bar) { MainMenu(bar); }); Sizeable().Zoomable(); WhenClose = THISBACK(Destroy); menubar.WhenHelp = toolbar.WhenHelp = statusbar; diff --git a/reference/CustomTitleBar/CustomTitleBar.upp b/reference/CustomTitleBar/CustomTitleBar.upp new file mode 100644 index 000000000..5872304d3 --- /dev/null +++ b/reference/CustomTitleBar/CustomTitleBar.upp @@ -0,0 +1,9 @@ +uses + CtrlLib; + +file + main.cpp; + +mainconfig + "" = "GUI"; + diff --git a/reference/CustomTitleBar/main.cpp b/reference/CustomTitleBar/main.cpp new file mode 100644 index 000000000..375d560a5 --- /dev/null +++ b/reference/CustomTitleBar/main.cpp @@ -0,0 +1,69 @@ +#include + +using namespace Upp; + +struct MyApp : TopWindow { + FrameTop bararea; // we represent whole TitleBar area as frame + ParentCtrl barrect; // to do custom caption clipping + MenuBar menubar; + LineEdit editor; + Label title; + + void MainMenu(Bar& bar) + { + bar.Sub("File", [=](Bar& bar) { + bar.Add("Exit", [=] { Break(); }); + }); + } + + void SetMenuBar() { + menubar.Set([=](Bar& bar) { + MainMenu(bar); + }); + } + + bool IsCustomTitleBarDragArea(Point p) override + { // identifies which titlebar areas can be clicked for dragging the window + p += GetScreenRect().TopLeft(); + return !menubar.GetScreenRect().Contains(p); + } + + MyApp() { + Sizeable().Zoomable(); + + Icon(CtrlImg::new_doc()); + + int h = menubar.GetStdHeight(); + CustomTitleBar(h); // h is suggested minimum height + + if(IsCustomTitleBar() && 0) { + menubar.Transparent(); + auto cm = GetCustomTitleBarMetrics(); + bararea.Height(cm.height); + AddFrame(bararea); + bararea << barrect.VSizePos().HSizePos(cm.lm, cm.rm); + ImageBuffer m(1, 2); + m[0][0] = Blend(SWhite(), SLtCyan()); + m[0][1] = Blend(SWhite(), SLtMagenta()); + bararea.Background(Image(m)); // simple gradient + barrect << menubar; + SetMenuBar(); // run it here to get GetWidth + menubar.LeftPos(0, menubar.GetWidth()).TopPos((cm.height - h) / 2, h); + barrect << title.HSizePos(menubar.GetWidth(), cm.rm).VSizePos(); + title.SetLabel("This is CustomTitleBar example"); + title.AlignCenter(); + title.AlignVCenter(); + } + else { // if it is not supported + AddFrame(menubar); + SetMenuBar(); + Title("This is CustomTitleBar example - CustomTitleBar not active"); + } + Add(editor.SizePos()); + }; +}; + +GUI_APP_MAIN +{ + MyApp().Run(); +} diff --git a/uppsrc/CtrlCore/TopWindow.cpp b/uppsrc/CtrlCore/TopWindow.cpp index e29608900..59c1b3b58 100644 --- a/uppsrc/CtrlCore/TopWindow.cpp +++ b/uppsrc/CtrlCore/TopWindow.cpp @@ -423,9 +423,9 @@ TopWindow& TopWindow::Icon(const Image& smallicon, const Image& _largeicon) bool is_custom_titlebar_available__; -bool TopWindow::IsCustomTitleBarAvailable() +bool TopWindow::IsCustomTitleBar() const { - return is_custom_titlebar_available__; + return custom_titlebar && is_custom_titlebar_available__; } TopWindow& TopWindow::CustomTitleBar(int cy) diff --git a/uppsrc/CtrlCore/TopWindow.h b/uppsrc/CtrlCore/TopWindow.h index 8a6d385a5..19b62f855 100644 --- a/uppsrc/CtrlCore/TopWindow.h +++ b/uppsrc/CtrlCore/TopWindow.h @@ -181,9 +181,8 @@ public: TopWindow& LargeIcon(const Image& m); TopWindow& Icon(const Image& smallicon, const Image& largeicon); - static bool IsCustomTitleBarAvailable(); TopWindow& CustomTitleBar(int min_cy = 0); - bool IsCustomTitleBar() const { return custom_titlebar && IsCustomTitleBarAvailable(); } + bool IsCustomTitleBar() const; struct CustomTitleBarMetrics { int lm; diff --git a/uppsrc/CtrlCore/src.tpp/TopWindow_en-us.tpp b/uppsrc/CtrlCore/src.tpp/TopWindow_en-us.tpp index 1b9019636..f7804bf98 100644 --- a/uppsrc/CtrlCore/src.tpp/TopWindow_en-us.tpp +++ b/uppsrc/CtrlCore/src.tpp/TopWindow_en-us.tpp @@ -505,6 +505,40 @@ e.g. in task switcher and other places (platform specific).&] [s7;%% [*/ Return value]-|`*this.&] [s3;%% &] [s4; &] +[s5;:Upp`:`:TopWindow`:`:CustomTitleBar`(int`): TopWindow[@(0.0.255) `&] +[* CustomTitleBar]([@(0.0.255) int] [*@3 min`_cy] [@(0.0.255) `=] [@3 0])&] +[s2;%% Attempts to activate where window client area extends into +its titlebar area. Window controls and icon still work (eating +some space on sides that can be queried by GetTitleBarMetrics). +[%-*@3 min`_cy] suggests minimal height of title bar area (so that +it will fit requested features), host might ignore this suggestion. +Windows title is not drawn.&] +[s3; &] +[s4; &] +[s5;:Upp`:`:TopWindow`:`:IsCustomTitleBar`(`)const: [@(0.0.255) bool] +[* IsCustomTitleBar]() [@(0.0.255) const]&] +[s2;%% Returns true if custom titlebar is active. (it can be inactive +even when CustomTitleBar was called).&] +[s3; &] +[s4; &] +[s5;:Upp`:`:TopWindow`:`:GetCustomTitleBarMetrics`(`)const: CustomTitleBarMetrics +[* GetCustomTitleBarMetrics]() [@(0.0.255) const]&] +[s2;%% Returns custom titlebar metrics based on active window features. +It works even before the window is opened. Returns&] +[s0;l288;%% &] +[s0;l288;%% -|struct CustomTitleBarMetrics `{&] +[s2;%% -|-|int [@(0.0.255) lm];&] +[s2;%% -|-|int [@(0.0.255) rm];&] +[s2;%% -|-|int [@(0.0.255) height];&] +[s2;%% -|-|Color [@(0.0.255) background];&] +[s2;%% -|`};&] +[s2;%% &] +[s2;%% where [@(0.0.255) lm ]/ [@(0.0.255) rm ]are spaces consumed by +windows decoration on the left / right side of area, [@(0.0.255) height +]is the height of title bar and background is a color that host +would use to draw the background of title bar area.&] +[s3; &] +[s4; &] [s5;:TopWindow`:`:SerializePlacement`(Stream`&`,bool`): [@(0.0.255) void]_[* SerializePla cement]([_^Stream^ Stream][@(0.0.255) `&]_[*@3 s], [@(0.0.255) bool]_[*@3 reminimize]_`=_[@(0.0.255) f alse])&]