Custom Title Bar refactored / gtk support (#345)

This commit is contained in:
mirek-fidler 2026-01-16 19:26:25 +01:00 committed by GitHub
parent 68dbd76e01
commit 241cc4ea9d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
48 changed files with 1606 additions and 538 deletions

View file

@ -0,0 +1,12 @@
uses
CtrlLib;
file
main.cpp;
mainconfig
"" = "GUI",
"" = "GUI FORCE_CSD",
"" = "GUI FORCE_CSD NOCUSTOMBAR",
"" = "GUI WAYLAND";

View file

@ -0,0 +1,112 @@
#include <CtrlLib/CtrlLib.h>
using namespace Upp;
struct TestRect : Ctrl {
void Paint(Draw& w) override {
Size sz = GetSize();
return;
w.DrawRect(sz, Yellow());
DrawFatFrame(w, sz, LtGreen(), 8);
DrawFatFrame(w, sz, Red(), 2);
for(int i = 0; i < 100; i++)
w.DrawText(i * 100, 2, AsString(i));
}
};
struct MyApp : TopWindow {
FrameTop<StaticRect> bararea; // we represent whole TitleBar area as frame
ParentCtrl barrect; // to do custom caption clipping
MenuBar menubar, menu2;
LineEdit editor;
Label title;
Label label;
TestRect rect;
Button button, button2;
bool zooming = true;
WithDropChoice<EditString> ed;
void MainMenu(Bar& bar)
{
bar.Sub("File", [=](Bar& bar) {
bar.Add("Zooming", [=] {
zooming = !zooming;
Zoomable(zooming);
});
bar.Add("Yellow", [=] { CustomTitleBar(Yellow()); });
bar.Add("Cyan", [=] { CustomTitleBar(Cyan()); });
bar.Add("LtCyan", [=] { CustomTitleBar(LtCyan()); });
bar.Add("Blue", [=] { CustomTitleBar(Blue()); });
bar.Add("Gray", [=] { CustomTitleBar(Gray()); });
bar.Separator();
bar.Add("GTK dialog", [=] {
FileSelNative sel;
sel.ActiveDir(GetHomeDirectory());
sel.ExecuteSelectDir("Just a test");
});
bar.Add("U++ dialog", [=] {
SelectFileOpen("Text files\t*.txt\nAll files\t*.*");
});
bar.Separator();
bar.Add("Exit", [=] { Break(); });
});
}
void SetMenuBar() {
menubar.Set([=](Bar& bar) {
MainMenu(bar);
});
}
virtual void Layout() override
{
String s = IsMinimized() ? "Minimized" : IsMaximized() ? "Maximized" : "Overlapped";
Title(s);
// LOG("Layout " << s << ", rect: " << GetScreenRect() << ", mousepos: " << GetMousePos());
}
MyApp() {
Sizeable().Zoomable();
Icon(CtrlImg::new_doc());
AddFrame(menubar);
SetMenuBar();
Title("This is CustomTitleBar example - CustomTitleBar not active");
Add(editor.SizePos());
Ctrl *tb = CustomTitleBar(LtCyan(), GetStdFontCy() + DPI(4));
if(tb) {
// *tb << label.SizePos();
*tb << rect.SizePos();
rect.IgnoreMouse();
rect.SetFrame(BlackFrame());
rect << label.SizePos();
label.SetLabel("\1[g= This is test");
button.SetLabel("Close");
*tb << button.RightPos(DPI(2), DPI(100)).VSizePos(2, 2);
button << [=] {
Break();
};
*tb << ed.RightPos(DPI(110), DPI(100)).VSizePos(2, 2);
button2.SetLabel("RefreshF");
*tb << button2.RightPos(DPI(222), DPI(100)).VSizePos(2, 2);
button2 << [=] {
RefreshFrame();
};
for(int i = 0; i < 200; i++)
ed.AddList(AsString(i));
}
String txt;
for(int i = 0; i < 200; i++)
txt << i << '\n';
editor <<= txt;
DDUMP(rect.IsIgnoreMouse());
};
};
GUI_APP_MAIN
{
MyApp().Run();
}

View file

@ -1,55 +0,0 @@
#include <CtrlLib/CtrlLib.h>
using namespace Upp;
struct MyApp : TopWindow {
void Paint(Draw& w) override {
Size sz = GetSize();
// w.DrawRect(sz, WhiteGray()); return;
auto h = GetCustomTitleBarMetrics().height;
Color c2 = SLtCyan();
for(int i = 0; i < h; i++)
w.DrawRect(0, i, sz.cx, 1, Blend(WhiteGray(), c2, i * 255 / h));
}
void Layout() override {
auto m = GetCustomTitleBarMetrics();
int h = bar.GetHeight();
bar.LeftPos(m.lm, bar.GetWidth()).TopPos((m.height - h) / 2, h);
}
void MainMenu(Bar& bar)
{
bar.Sub("File", [=](Bar& bar) {
bar.Add("Exit", [=] { Break(); });
});
}
MenuBar bar;
LineEdit editor;
MyApp() {
Icon(CtrlImg::select_all());
CustomTitleBar(200);
Add(bar);
bar.Transparent();
bar.Set([=](Bar& bar) {
MainMenu(bar);
});
DDUMP(bar.GetWidth());
DDUMP(bar.GetHeight());
DDUMP(GetCustomTitleBarMetrics().height);
Add(editor.VSizePos(GetCustomTitleBarMetrics().height).HSizePos());
};
};
GUI_APP_MAIN
{
MyApp().Sizeable().Zoomable().Run();
}

View file

@ -0,0 +1,53 @@
#include <CtrlLib/CtrlLib.h>
using namespace Upp;
struct MyApp : TopWindow {
MenuBar bar;
LineEdit editor;
Label title;
void Layout() override {
if(IsCustomTitleBar()) {
int ch = GetCustomTitleBarMetrics().height;
int h = bar.GetHeight();
int w = bar.GetWidth();
bar.LeftPos(0, w).TopPos((ch - h) / 2, h);
title.HSizePos(w, 0).VSizePos();
}
}
MyApp() {
Sizeable().Zoomable();
Icon(CtrlImg::select_all());
Ctrl *tb = CustomTitleBar(Blend(SWhiteGray(), SLtMagenta(), 50), 50);
if(tb) {
tb->Add(bar);
tb->Add(title);
bar.Transparent();
}
else
AddFrame(bar);
bar.Set([=](Bar& bar) {
bar.Sub("File", [=](Bar& bar) {
bar.Add("Yellow", [=] { CustomTitleBar(Yellow(), 20); });
bar.Add("Red", [=] { CustomTitleBar(LtRed(), 20); });
bar.Add("Exit", [=] { Break(); });
});
});
title = "\1[g This is [* title";
title.AlignCenter();
Add(editor.SizePos());
};
};
GUI_APP_MAIN
{
MyApp().Sizeable().Zoomable().Run();
}

12
upptst/GUI/GUI.upp Normal file
View file

@ -0,0 +1,12 @@
uses
CtrlLib;
file
main.cpp;
mainconfig
"" = "GUI",
"" = "GUI FORCE_CSD",
"" = "GUI FORCE_CSD NOCUSTOMBAR",
"" = "GUI WAYLAND";

100
upptst/GUI/main.cpp Normal file
View file

@ -0,0 +1,100 @@
#include <CtrlLib/CtrlLib.h>
using namespace Upp;
struct TestRect : Ctrl {
void Paint(Draw& w) override {
Size sz = GetSize();
return;
w.DrawRect(sz, Yellow());
DrawFatFrame(w, sz, LtGreen(), 8);
DrawFatFrame(w, sz, Red(), 2);
for(int i = 0; i < 100; i++)
w.DrawText(i * 100, 2, AsString(i));
}
};
struct MyApp : TopWindow {
FrameTop<StaticRect> bararea; // we represent whole TitleBar area as frame
ParentCtrl barrect; // to do custom caption clipping
MenuBar menubar, menu2;
LineEdit editor;
Label title;
Label label;
TestRect rect;
Button button;
bool zooming = true;
WithDropChoice<EditString> ed;
void MainMenu(Bar& bar)
{
bar.Sub("File", [=](Bar& bar) {
bar.Add("Zooming", [=] {
zooming = !zooming;
Zoomable(zooming);
});
bar.Add("Yellow", [=] { CustomTitleBar(Yellow()); });
bar.Add("Cyan", [=] { CustomTitleBar(Cyan()); });
bar.Add("LtCyan", [=] { CustomTitleBar(LtCyan()); });
bar.Add("Blue", [=] { CustomTitleBar(Blue()); });
bar.Add("Gray", [=] { CustomTitleBar(Gray()); });
bar.Separator();
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);
}
virtual void Layout() override
{
String s = IsMinimized() ? "Minimized" : IsMaximized() ? "Maximized" : "Overlapped";
Title(s);
DLOG("Layout " << s << ", rect: " << GetScreenRect() << ", mousepos: " << GetMousePos());
}
MyApp() {
Sizeable().Zoomable();
Icon(CtrlImg::new_doc());
AddFrame(menubar);
SetMenuBar();
Title("This is CustomTitleBar example - CustomTitleBar not active");
Add(editor.SizePos());
Ctrl *tb = CustomTitleBar(LtCyan(), GetStdFontCy() + DPI(4));
if(tb) {
// *tb << label.SizePos();
*tb << rect.SizePos();
rect.SetFrame(BlackFrame());
rect << label.SizePos();
label.SetLabel("\1[g= This is test");
button.SetLabel("Close");
rect << button.RightPos(DPI(2), DPI(100)).VSizePos(2, 2);
button << [=] {
Break();
};
rect << ed.RightPos(DPI(110), DPI(100)).VSizePos(2, 2);
for(int i = 0; i < 200; i++)
ed.AddList(AsString(i));
}
String txt;
for(int i = 0; i < 200; i++)
txt << i << '\n';
editor <<= txt;
};
};
GUI_APP_MAIN
{
MyApp().Run();
}

View file

@ -0,0 +1,10 @@
uses
CtrlLib;
file
main.cpp;
mainconfig
"" = "GUI",
"" = "GUI FORCE_CSD";

View file

@ -0,0 +1,92 @@
#include <CtrlLib/CtrlLib.h>
using namespace Upp;
struct App : public TopWindow
{
DropList dl;
Button move;
void Paint(Draw& w) override {
w.DrawRect(GetSize(), LtCyan());
DrawFrame(w, 0, 0, 500, 500, Black());
DrawFrame(w, 0, 0, 400, 400, Black());
DrawFrame(w, 0, 0, 600, 600, Black());
w.DrawText(10, 10, AsString(GetScreenView()));
w.DrawText(10, 50, AsString(GetScreenRect()));
w.DrawText(10, 90, AsString(GetRect()));
w.DrawText(10, 130, AsString(GetMousePos()));
}
void MouseMove(Point p, dword keyflags) override {
Refresh();
}
void Layout() override {
Refresh();
}
Size GetMinSize() const override {
return Size(400, 400);
}
Size GetMaxSize() const override {
return Size(600, 600);
}
typedef App CLASSNAME;
App()
{
SetRect(100, 200, 500, 500);
Sizeable().Zoomable();
Add(dl.LeftPos(10, 101).BottomPos(0));
for(int i = 0; i < 20; i++)
dl.Add(i);
Add(move.HSizePos(120, 0).BottomPosZ(0, 24));
move.SetLabel("Move to 320, 420, 400");
move << [=] {
DLOG("================ MOVE");
SetRect(320, 420, 400, 400);
};
}
};
struct App2 : App {
Label title;
App2(int h = GetStdFontCy() + DPI(4)) {
SetRect(700, 200, 500, 500);
Ctrl *tb = CustomTitleBar(SYellow(), h);
if(tb)
*tb << title.SizePos();
title = "\1[g= [* custom [/_ titlebar";
}
};
GUI_APP_MAIN
{
App app, app_csd;
App2 app2, app3(DPI(128));
app.Title("SSD");
app.OpenMain();
#ifdef PLATFORM_POSIX
app_csd.Title("CSD");
app_csd.Force_csd_();
app_csd.SetRect(1300, 200, 500, 500);
app_csd.OpenMain();
#endif
app2.OpenMain();
app3.SetRect(1900, 200, 500, 500);
app3.OpenMain();
app.Run();
}