diff --git a/examples/CustomTitlebar/CustomTitlebar.upp b/examples/CustomTitlebar/CustomTitlebar.upp new file mode 100644 index 000000000..5872304d3 --- /dev/null +++ b/examples/CustomTitlebar/CustomTitlebar.upp @@ -0,0 +1,9 @@ +uses + CtrlLib; + +file + main.cpp; + +mainconfig + "" = "GUI"; + diff --git a/examples/CustomTitlebar/main.cpp b/examples/CustomTitlebar/main.cpp new file mode 100644 index 000000000..a1b069a2c --- /dev/null +++ b/examples/CustomTitlebar/main.cpp @@ -0,0 +1,34 @@ +#include + +using namespace Upp; + +struct MyApp : TopWindow { + void Paint(Draw& w) override { + Size sz = GetSize(); + w.DrawRect(sz, LtCyan()); + } + + void MainMenu(Bar& bar) + { + bar.Sub("File", [=](Bar& bar) { + bar.Add("Exit", [=] { Break(); }); + }); + } + + MenuBar bar; + + MyApp() { + CustomTitleBar(); + Add(bar.LeftPos(0, 300).TopPos(0, 30)); + bar.Set([=](Bar& bar) { + MainMenu(bar); + }); + }; +}; + +GUI_APP_MAIN +{ + TopWindow win; + win.Sizeable().Zoomable().OpenMain(); + MyApp().Sizeable().Zoomable().Run(); +} diff --git a/uppsrc/CtrlCore/CtrlCore.iml b/uppsrc/CtrlCore/CtrlCore.iml index 0c8c09f38..390948ddc 100644 --- a/uppsrc/CtrlCore/CtrlCore.iml +++ b/uppsrc/CtrlCore/CtrlCore.iml @@ -1,4 +1,8 @@ PREMULTIPLIED +IMAGE_ID(WinClose__UHD) +IMAGE_ID(WinMinimize__UHD) +IMAGE_ID(WinMaximize__UHD) +IMAGE_ID(WinMaximized__UHD) IMAGE_ID(DndMoveX11) IMAGE_ID(DndMove) IMAGE_ID(DndMove98) @@ -7,69 +11,109 @@ IMAGE_ID(DndNone98) IMAGE_ID(DndCopy) IMAGE_ID(DndCopy98) IMAGE_ID(DndData) +IMAGE_ID(WinClose) +IMAGE_ID(WinMinimize) +IMAGE_ID(WinMaximize) +IMAGE_ID(WinMaximized) IMAGE_BEGIN_DATA -IMAGE_DATA(120,156,237,154,73,104,20,81,20,69,111,28,18,68,193,41,110,2,106,16,146,149,136,40,89,56,196,49,160,40,138,18) -IMAGE_DATA(69,112,222,24,136,11,21,23,1,21,135,128,19,154,128,162,162,184,17,17,156,32,138,129,128,10,46,5,221,36,226,38) -IMAGE_DATA(104,4,179,48,196,40,132,160,136,35,105,239,163,171,210,157,174,95,169,174,238,252,87,189,168,7,151,174,254,93,93,231) -IMAGE_DATA(190,247,135,170,110,62,202,81,142,180,72,32,218,72,56,170,113,52,91,155,47,225,120,184,67,213,41,123,72,184,225,120) -IMAGE_DATA(104,83,246,144,72,143,8,60,36,50,67,217,131,135,175,236,193,200,87,244,224,203,87,242,48,34,95,193,67,32,223,178) -IMAGE_DATA(135,32,166,171,94,170,157,58,79,85,218,226,195,187,30,9,247,3,245,26,118,214,71,79,190,6,190,176,175,193,206,253) -IMAGE_DATA(33,147,213,107,240,32,252,83,22,216,64,170,127,159,35,89,231,54,3,95,218,165,246,53,150,248,123,168,251,72,141,239) -IMAGE_DATA(165,6,15,54,107,32,121,29,194,240,177,165,89,3,97,86,194,155,155,95,13,180,194,175,6,154,145,206,142,130,47,125) -IMAGE_DATA(82,231,112,221,245,71,59,196,67,84,207,167,113,196,17,71,28,118,162,64,255,12,168,112,52,69,155,159,118,179,149,27) -IMAGE_DATA(205,98,101,15,153,55,252,6,101,15,166,31,32,154,30,252,126,4,105,121,240,240,149,61,24,249,138,30,124,249,74,30) -IMAGE_DATA(70,228,43,120,8,228,91,246,16,196,116,213,74,93,162,54,83,165,182,248,240,174,71,194,189,77,93,132,157,245,209,147) -IMAGE_DATA(175,129,47,236,29,176,115,127,200,100,181,26,60,8,127,189,5,54,144,234,223,99,72,214,185,193,192,151,118,169,125,133) -IMAGE_DATA(37,126,21,181,31,169,241,93,110,240,96,179,6,146,215,10,12,31,91,154,53,16,102,41,188,185,105,214,192,20,154,53) -IMAGE_DATA(240,245,144,198,142,130,47,181,94,236,112,163,120,62,115,61,68,245,124,26,71,28,113,196,97,39,10,244,207,128,200,248) -IMAGE_DATA(105,55,219,200,248,17,122,48,253,0,137,140,31,129,7,15,95,217,131,145,175,232,193,151,175,228,97,68,190,130,135,64) -IMAGE_DATA(190,101,15,65,76,213,252,161,191,30,121,242,141,130,159,193,210,244,96,98,104,243,141,237,202,253,80,40,124,223,177,232) -IMAGE_DATA(190,118,119,119,15,123,31,244,26,22,158,121,141,76,63,57,188,230,146,255,208,251,176,57,100,230,98,251,59,1,151,203) -IMAGE_DATA(55,255,188,224,136,243,143,243,183,252,157,128,203,229,154,255,168,189,134,133,91,240,16,135,95,20,232,159,1,241,206,0) -IMAGE_DATA(196,59,3,34,240,224,225,43,123,48,242,21,61,248,242,149,60,140,200,87,240,16,200,183,236,33,136,233,42,222,25,80) -IMAGE_DATA(88,59,3,138,139,128,237,43,129,174,179,192,224,85,158,119,18,248,55,23,120,137,112,91,217,93,70,152,157,1,197,147) -IMAGE_DATA(128,230,211,192,192,77,224,231,58,224,83,21,240,110,55,208,211,66,47,7,129,222,18,224,48,207,27,147,37,63,212,206) -IMAGE_DATA(128,177,204,251,10,217,199,129,126,30,95,96,219,26,106,217,120,160,137,126,6,251,121,126,35,125,177,173,154,26,151,133) -IMAGE_DATA(135,80,59,3,104,162,235,5,240,119,34,112,157,239,217,5,152,199,124,27,105,228,91,7,249,156,32,189,111,249,157,153) -IMAGE_DATA(192,99,126,86,70,21,5,240,67,237,12,104,38,131,185,127,229,241,86,106,62,181,239,50,240,171,147,237,236,255,118,38) -IMAGE_DATA(124,230,30,240,103,11,240,158,159,173,166,138,179,168,129,41,140,53,144,177,86,15,124,230,241,42,230,125,70,216,111,200) -IMAGE_DATA(174,72,142,61,89,31,234,111,0,63,118,2,221,60,174,165,38,231,200,7,82,227,115,104,103,64,19,199,57,107,61,192) -IMAGE_DATA(164,238,178,32,223,59,83,108,34,177,132,249,239,122,196,254,169,77,230,47,126,166,229,193,247,236,12,224,96,125,249,138) -IMAGE_DATA(76,154,25,236,112,106,238,112,150,80,101,244,242,68,250,127,42,208,226,180,77,205,131,239,122,24,122,62,229,96,170,57) -IMAGE_DATA(194,49,214,71,6,59,183,135,109,39,168,109,212,134,25,192,173,7,192,239,189,192,23,121,79,45,164,38,228,201,247,4) -IMAGE_DATA(107,127,248,0,231,216,83,230,207,73,59,192,197,177,235,28,208,247,140,158,104,228,11,231,226,81,158,182,156,154,133,236) -IMAGE_DATA(214,129,176,33,215,172,158,206,57,182,145,253,76,254,199,181,92,131,56,39,31,178,157,75,18,150,81,115,168,18,11,108) -IMAGE_DATA(55,100,109,145,249,45,115,76,198,249,38,106,17,181,0,201,188,109,178,221,144,181,69,230,183,204,49,25,231,50,214,164) -IMAGE_DATA(191,109,212,60,142,56,70,53,254,3,214,248,59,155,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) -IMAGE_END_DATA(1056, 4) +IMAGE_DATA(120,156,237,150,91,10,194,64,16,4,61,142,231,240,254,119,138,136,54,129,128,178,143,217,157,238,118,10,242,23,72,117) +IMAGE_DATA(145,215,253,113,123,220,138,162,145,227,115,184,210,178,239,184,28,110,180,236,187,158,227,214,162,117,223,183,243,28,90,244) +IMAGE_DATA(110,115,108,49,186,201,169,197,236,22,135,22,81,27,148,91,68,187,43,182,88,229,172,212,98,181,171,66,139,93,142,204) +IMAGE_DATA(45,118,187,49,182,200,114,98,106,145,237,146,125,125,22,135,108,15,150,6,153,62,108,13,192,78,47,214,6,96,135,31) +IMAGE_DATA(123,3,176,210,83,165,1,88,225,171,214,0,68,122,171,54,0,17,254,234,13,192,204,14,151,6,96,100,143,91,3,208) +IMAGE_DATA(179,203,181,1,104,217,231,222,0,252,218,249,47,13,64,53,56,169,6,39,213,224,77,117,168,231,226,69,189,39,235,187) +IMAGE_DATA(249,162,254,163,250,246,185,182,24,217,229,214,98,102,143,75,139,136,29,234,45,34,253,85,91,172,240,86,107,177,210,87) +IMAGE_DATA(165,197,14,79,246,22,59,253,88,91,100,120,177,181,200,244,97,105,193,224,145,237,144,125,125,6,23,166,6,89,78,140) +IMAGE_DATA(13,192,46,55,230,6,96,181,163,66,3,176,202,85,169,1,136,118,86,108,0,162,220,149,27,128,217,13,14,13,192,232) +IMAGE_DATA(22,167,6,160,119,147,99,3,208,179,205,181,1,152,185,39,220,24,121,71,184,226,190,175,8,224,9,0,58,37,178,0) +IMAGE_END_DATA(320, 1) IMAGE_BEGIN_DATA -IMAGE_DATA(120,156,237,152,191,107,21,65,16,199,7,44,108,45,2,182,175,201,159,96,147,66,108,37,41,180,16,65,5,65,65,124) -IMAGE_DATA(41,69,210,4,130,54,70,144,136,198,31,77,8,18,181,139,4,12,54,41,132,88,90,8,81,17,212,66,196,128,18,33) -IMAGE_DATA(70,48,106,252,1,227,204,187,61,223,102,111,247,126,228,237,206,70,220,47,76,178,55,119,236,231,59,187,123,123,239,14) -IMAGE_DATA(90,208,2,77,8,113,133,145,61,32,43,162,7,204,21,201,3,234,138,224,1,77,9,123,40,240,133,61,88,249,130,30) -IMAGE_DATA(156,124,33,15,165,124,1,15,149,252,192,30,170,152,162,245,131,252,126,84,168,55,6,223,96,213,241,176,155,255,180,233) -IMAGE_DATA(252,56,197,117,138,243,20,39,155,123,182,49,170,248,29,246,4,157,187,69,209,214,98,142,98,180,153,7,215,181,165,30) -IMAGE_DATA(166,41,119,193,146,159,162,220,39,199,185,134,114,242,185,206,69,75,255,147,148,91,162,56,66,241,108,107,115,81,203,195) -IMAGE_DATA(101,106,95,52,250,190,73,199,47,21,155,143,103,3,242,121,173,157,213,142,153,253,84,99,179,242,117,209,35,31,192,178) -IMAGE_DATA(62,185,254,107,42,55,105,212,157,235,62,29,159,240,195,223,107,38,184,174,199,20,183,181,249,54,175,241,52,255,78,241) -IMAGE_DATA(250,94,161,24,180,48,230,252,141,125,169,206,16,99,129,98,140,98,88,237,65,124,124,188,200,222,25,202,3,143,241,49) -IMAGE_DATA(85,239,161,192,99,190,77,181,3,212,126,108,40,216,152,39,37,121,211,54,253,24,208,175,98,151,52,95,123,216,158,162) -IMAGE_DATA(24,16,246,96,62,240,71,132,61,216,94,64,36,61,184,94,130,164,60,20,248,194,30,172,124,65,15,78,190,144,135,82) -IMAGE_DATA(190,128,135,74,126,96,15,85,204,60,230,41,174,80,28,164,232,11,197,135,226,126,196,220,25,138,75,16,102,127,44,212) -IMAGE_DATA(107,225,51,251,40,132,121,62,152,172,121,139,7,230,15,6,96,3,116,231,151,222,225,59,227,60,98,225,115,158,199,190) -IMAGE_DATA(63,16,127,15,197,48,116,215,119,203,226,65,31,3,115,109,218,98,191,234,167,142,184,174,125,176,121,109,149,141,1,94) -IMAGE_DATA(189,135,120,122,2,241,240,57,196,3,163,89,112,155,115,234,250,33,229,161,142,152,217,7,197,249,117,141,1,62,90,66) -IMAGE_DATA(156,122,128,56,126,55,59,55,54,157,181,57,167,174,189,1,157,247,214,158,228,26,3,124,245,14,241,225,19,196,217,197) -IMAGE_DATA(236,220,157,133,172,205,57,143,124,128,238,124,206,232,252,15,171,133,253,169,19,207,223,120,231,243,156,12,40,110,190,255) -IMAGE_DATA(224,231,117,196,229,143,136,175,151,51,222,139,183,89,155,115,158,249,185,7,253,247,41,126,251,129,184,246,5,113,101,45) -IMAGE_DATA(227,189,95,205,218,156,11,192,55,133,191,126,35,110,252,68,252,186,129,184,254,61,11,110,115,78,130,95,35,66,242,249) -IMAGE_DATA(190,30,82,12,87,52,185,255,155,170,165,250,110,151,68,147,253,47,41,41,142,182,233,199,128,104,124,237,97,27,141,31) -IMAGE_DATA(209,131,237,5,36,26,63,130,135,2,95,216,131,149,47,232,193,201,23,242,80,202,23,240,80,201,15,236,161,138,41,90) -IMAGE_DATA(63,200,239,71,133,122,99,240,13,150,164,7,27,67,154,111,205,151,120,168,243,50,208,179,175,50,126,192,123,213,185,22) -IMAGE_DATA(109,121,243,158,49,175,105,234,197,100,185,250,172,226,27,255,183,82,255,223,99,75,13,155,60,233,161,215,220,75,253,117) -IMAGE_DATA(60,86,140,191,173,150,186,22,188,240,165,234,55,5,2,245,215,136,144,245,55,233,46,68,253,181,59,130,127,183,126,111) -IMAGE_DATA(255,155,194,3,120,72,114,169,149,62,88,37,37,37,37,37,37,37,37,233,250,223,127,12,123,251,1,221,75,253,62,248) -IMAGE_DATA(144,234,79,245,167,250,211,199,128,36,167,254,0,206,90,25,174,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) -IMAGE_END_DATA(864, 4) +IMAGE_DATA(120,156,237,219,59,14,130,64,0,69,81,58,89,10,139,96,255,219,194,74,11,33,195,39,145,225,205,156,147,188,210,100) +IMAGE_DATA(174,1,26,113,154,135,121,0,0,0,0,0,128,63,91,204,204,236,145,3,0,0,0,0,0,0,58,49,29,248,51,225) +IMAGE_DATA(242,26,199,239,134,250,63,104,30,218,198,153,119,59,11,159,125,252,10,103,46,182,54,216,251,219,92,253,172,55,173,199) +IMAGE_DATA(222,218,103,184,117,7,238,211,52,197,198,19,247,120,146,43,189,233,206,92,195,77,245,30,92,58,189,122,245,230,210,171) +IMAGE_DATA(87,111,46,189,122,245,230,210,171,87,111,46,189,122,245,230,210,171,87,111,46,189,122,245,230,210,171,87,111,46,189,122) +IMAGE_DATA(245,230,210,171,87,111,174,205,174,222,222,39,244,190,104,124,243,153,107,184,135,109,126,39,141,238,163,246,57,238,238,93) +IMAGE_DATA(53,39,94,243,23,158,189,173,246,238,105,165,119,229,13,34,7,85,191,0,0,0,0,0,0,0,0,0,0,0,0,0) +IMAGE_END_DATA(224, 2) + +IMAGE_BEGIN_DATA +IMAGE_DATA(120,156,237,154,49,82,195,48,16,69,213,145,91,64,149,225,16,46,115,15,186,212,28,129,146,11,112,2,26,46,144,134) +IMAGE_DATA(27,208,112,2,250,28,195,104,7,139,152,72,182,23,89,218,93,219,255,49,219,48,138,254,127,178,113,152,73,238,27,215) +IMAGE_DATA(184,66,180,10,163,133,134,171,166,187,182,171,164,183,182,159,164,183,182,147,180,179,182,143,133,251,91,138,45,58,7,224) +IMAGE_DATA(188,13,103,2,206,235,247,37,114,157,219,155,221,238,119,38,246,169,54,137,14,165,125,199,178,44,248,178,174,21,211,153) +IMAGE_DATA(155,101,193,55,215,153,115,38,150,7,190,203,246,41,238,204,248,59,213,102,170,51,251,117,137,215,90,115,13,72,248,90) +IMAGE_DATA(163,136,239,200,88,163,246,51,203,26,240,133,47,103,61,124,225,107,1,248,194,151,179,30,190,240,181,0,124,225,203,89) +IMAGE_DATA(15,95,248,90,0,190,240,229,172,135,47,124,45,0,95,248,114,214,111,201,55,103,31,45,230,248,206,217,71,139,92,223) +IMAGE_DATA(185,251,104,81,170,39,124,87,236,187,226,207,67,147,172,248,243,238,36,43,254,62,3,123,191,133,77,14,218,157,37,93) +IMAGE_DATA(183,232,27,57,47,252,251,132,255,118,54,238,91,26,171,190,243,185,243,63,125,209,34,155,230,19,196,14,221,220,74,231) +IMAGE_DATA(19,93,135,87,63,71,225,14,109,160,235,112,18,238,208,246,81,232,208,94,35,220,33,202,23,238,144,204,23,236,48,152) +IMAGE_DATA(47,212,97,52,95,160,195,100,126,229,14,83,153,97,206,126,62,253,60,251,217,215,202,119,241,243,136,114,191,252,124,184) +IMAGE_DATA(58,207,199,200,55,145,79,217,47,174,206,251,195,117,214,57,209,129,242,159,42,100,59,119,185,190,239,238,231,156,79,137) +IMAGE_DATA(124,250,61,157,253,161,82,254,131,159,55,119,185,191,155,68,135,154,103,64,94,143,238,239,189,37,121,6,148,185,119,177) +IMAGE_DATA(219,208,25,72,49,116,6,146,244,179,53,242,233,154,28,187,220,240,252,145,134,58,104,253,127,10,0,0,85,248,6,45) +IMAGE_DATA(43,44,163,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) +IMAGE_END_DATA(480, 2) + +IMAGE_BEGIN_DATA +IMAGE_DATA(120,156,237,154,91,136,77,81,24,199,255,227,50,147,40,183,145,82,52,169,121,147,68,30,144,113,45,50,17,33,229,30) +IMAGE_DATA(81,51,15,212,36,133,144,114,203,45,204,132,72,226,129,16,226,137,7,229,69,241,98,152,23,151,121,48,15,52,102,212) +IMAGE_DATA(52,145,92,155,237,255,57,123,159,115,236,189,246,217,103,159,115,214,90,231,97,127,245,157,189,215,218,251,236,223,255,251) +IMAGE_DATA(214,229,156,181,91,168,65,13,178,204,129,93,115,92,175,117,125,152,105,190,152,171,97,43,125,186,97,13,142,103,174,134) +IMAGE_DATA(157,134,53,56,217,102,65,131,227,55,195,26,2,124,195,26,148,124,131,26,66,249,134,52,228,228,27,208,16,201,215,172) +IMAGE_DATA(33,138,233,249,3,250,105,250,50,122,181,46,62,130,243,145,112,175,210,143,67,207,252,24,136,87,193,23,246,26,232,249) +IMAGE_DATA(125,240,179,30,40,52,8,191,94,3,27,200,180,239,30,164,242,188,83,193,151,122,201,125,173,38,254,84,122,35,50,253) +IMAGE_DATA(187,70,161,65,103,14,36,174,217,248,191,111,153,204,129,48,171,17,140,205,100,14,84,102,50,7,161,26,178,216,54,248) +IMAGE_DATA(146,235,233,46,215,198,255,51,79,131,173,255,167,137,37,150,88,98,122,172,76,95,6,88,227,103,253,216,90,227,91,212) +IMAGE_DATA(160,90,128,88,227,91,208,16,224,27,214,160,228,27,212,16,202,55,164,33,39,223,128,134,72,190,102,13,81,76,163,241) +IMAGE_DATA(195,252,124,20,136,215,6,223,199,50,169,65,197,48,205,87,214,27,110,135,114,225,135,246,69,239,216,209,209,241,95,57) +IMAGE_DATA(234,24,23,238,127,134,95,79,1,199,66,226,79,151,227,198,224,143,69,247,119,34,30,87,108,252,69,193,145,196,159,196) +IMAGE_DATA(175,249,59,17,143,43,52,254,146,29,227,194,53,104,72,44,204,202,244,101,64,178,51,0,201,206,0,11,26,2,124,195) +IMAGE_DATA(26,148,124,131,26,66,249,134,52,228,228,27,208,16,201,215,172,33,138,233,121,178,51,160,188,118,6,84,86,0,171,231) +IMAGE_DATA(0,237,135,129,190,22,222,183,31,248,51,1,120,202,107,243,227,240,93,143,179,51,160,114,8,112,242,32,208,123,17,248) +IMAGE_DATA(190,8,248,48,21,120,187,30,248,120,135,90,182,3,157,85,64,19,239,235,151,39,63,214,206,128,254,140,187,153,236,189) +IMAGE_DATA(64,15,207,143,177,110,1,189,110,32,112,130,122,250,122,120,255,1,234,98,221,76,250,128,60,52,196,218,25,64,17,237) +IMAGE_DATA(143,129,223,131,129,243,44,179,9,48,145,241,30,160,144,47,173,228,115,128,116,182,241,59,99,129,123,188,54,134,94,17) +IMAGE_DATA(193,143,181,51,224,36,25,140,253,51,207,87,210,39,209,183,156,1,126,188,102,61,219,255,5,3,62,116,3,248,181,2) +IMAGE_DATA(120,199,107,243,232,149,121,228,64,101,202,28,72,95,107,0,62,241,124,46,227,62,36,236,151,100,215,166,250,158,204,15) +IMAGE_DATA(13,23,128,111,107,129,14,158,47,167,15,45,144,15,100,250,103,122,103,192,9,246,115,230,186,151,65,93,103,66,190,190) +IMAGE_DATA(206,176,137,196,12,198,191,238,46,219,103,121,42,126,209,51,162,8,126,96,103,0,59,235,211,103,100,82,76,95,171,155) +IMAGE_DATA(115,151,51,131,62,134,90,238,75,251,15,7,238,184,117,195,139,224,123,26,210,255,79,217,153,230,239,98,31,235,34,131) +IMAGE_DATA(141,251,145,117,251,232,171,232,139,71,1,87,110,2,63,55,2,221,82,166,79,161,15,42,146,31,48,230,190,105,27,199) +IMAGE_DATA(216,67,198,207,65,219,203,201,177,253,8,208,245,136,154,40,164,155,99,113,55,111,155,69,31,135,252,230,129,184,38,207) +IMAGE_DATA(156,57,146,99,108,9,219,153,252,247,11,57,7,113,76,222,98,61,167,36,212,209,199,211,171,52,176,61,147,185,69,198) +IMAGE_DATA(183,140,49,233,231,75,233,211,232,147,145,138,91,39,219,51,153,91,100,124,203,24,147,126,46,125,77,218,91,71,206,19) +IMAGE_DATA(75,172,180,86,166,47,3,172,241,179,126,108,173,241,45,106,80,45,64,172,241,45,104,8,240,13,107,80,242,13,106,8) +IMAGE_DATA(229,27,210,144,147,111,64,67,36,95,179,134,40,166,209,248,97,126,62,10,196,107,131,239,99,229,163,97,180,124,112,81) +IMAGE_DATA(230,240,79,184,211,146,90,0,59,155,227,107,86,49,162,248,255,216,92,148,58,87,82,11,195,180,115,17,230,236,137,167) +IMAGE_DATA(33,236,222,156,26,46,179,238,176,162,254,18,235,122,66,174,197,180,80,190,196,249,68,241,252,179,172,227,162,216,89,77) +IMAGE_DATA(111,43,172,45,242,210,112,138,231,71,125,207,62,199,242,27,151,45,229,219,26,249,210,215,118,100,149,133,253,42,139,45) +IMAGE_DATA(230,245,139,34,249,128,162,127,74,252,205,110,221,89,95,220,158,221,103,121,83,105,248,117,254,10,137,235,57,253,90,86) +IMAGE_DATA(123,251,239,41,81,251,135,154,244,111,121,25,80,175,96,220,45,93,238,115,90,19,25,178,248,223,71,111,116,231,32,41) +IMAGE_DATA(111,8,178,181,45,138,37,199,107,221,120,87,106,206,121,153,90,127,184,243,177,207,76,188,136,72,44,177,162,236,47,6) +IMAGE_DATA(32,123,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) +IMAGE_END_DATA(1152, 4) + +IMAGE_BEGIN_DATA +IMAGE_DATA(120,156,237,152,191,106,21,65,20,198,207,35,88,228,1,182,201,35,216,164,178,21,83,104,149,194,62,24,31,32,77,64) +IMAGE_DATA(236,82,72,192,20,86,193,34,104,103,170,96,99,33,232,3,8,130,88,104,17,66,2,17,3,33,66,98,140,70,248,220) +IMAGE_DATA(147,153,235,157,204,206,236,206,122,119,206,68,114,62,248,184,115,103,151,249,125,103,118,119,246,15,85,84,145,35,80,89) +IMAGE_DATA(193,122,218,250,154,52,159,101,51,204,215,158,17,206,128,145,108,134,69,225,12,112,85,32,3,124,9,103,104,240,133,51) +IMAGE_DATA(4,249,130,25,162,124,161,12,173,124,129,12,157,252,204,25,186,152,35,111,214,126,92,251,78,237,169,92,124,106,174,71) +IMAGE_DATA(204,93,175,253,136,242,172,143,141,122,3,124,102,223,165,60,247,7,159,181,25,200,192,252,91,25,216,68,227,227,187,68) +IMAGE_DATA(102,158,23,3,124,238,231,185,159,206,196,191,94,251,62,141,207,239,42,144,193,157,3,255,220,12,249,166,29,39,69,92) +IMAGE_DATA(215,13,186,120,110,181,205,1,86,55,128,123,43,192,220,67,224,246,146,49,183,185,207,238,63,107,51,164,136,153,83,212) +IMAGE_DATA(60,190,177,57,192,219,247,192,218,75,96,249,185,217,246,224,169,105,115,159,221,247,73,237,133,68,126,76,177,57,192,167) +IMAGE_DATA(29,224,245,59,224,197,27,179,237,217,43,211,230,190,1,249,68,227,227,185,238,242,191,28,52,214,167,115,127,216,26,156) +IMAGE_DATA(207,199,100,198,114,71,235,15,190,29,3,187,251,192,231,93,195,251,184,109,218,220,55,48,127,148,193,125,62,197,201,79) +IMAGE_DATA(224,240,8,248,122,104,120,123,7,166,205,125,25,248,190,112,246,27,56,253,5,124,63,5,142,127,24,115,155,251,36,248) +IMAGE_DATA(9,206,201,231,235,122,214,50,98,238,115,253,247,85,101,199,94,104,113,159,245,79,165,42,163,75,250,49,160,24,223,185) +IMAGE_DATA(217,22,227,23,204,16,122,1,41,198,47,144,161,193,23,206,16,228,11,102,136,242,133,50,180,242,5,50,116,242,51,103) +IMAGE_DATA(232,98,138,214,79,242,235,81,163,222,18,124,143,37,153,33,196,144,230,7,251,91,50,164,188,12,76,156,171,141,159,241) +IMAGE_DATA(90,141,158,139,161,126,255,154,241,247,233,155,197,103,197,198,236,226,123,191,255,82,255,223,255,129,26,46,100,114,237,214) +IMAGE_DATA(60,73,253,41,25,59,230,63,84,75,106,132,65,248,82,245,251,34,129,250,19,156,179,254,62,195,229,168,63,121,32,250) +IMAGE_DATA(127,235,31,236,183,47,60,67,6,85,76,149,126,176,82,169,84,42,149,74,165,114,117,213,31,134,7,123,128,158,164,254) +IMAGE_DATA(33,248,164,245,107,253,90,191,126,12,80,69,245,7,245,218,88,188,0,0,0,0,0,0,0,0,0,0,0,0,0,0) +IMAGE_END_DATA(608, 3) diff --git a/uppsrc/CtrlCore/CtrlDraw.cpp b/uppsrc/CtrlCore/CtrlDraw.cpp index 283ec5a6c..c79fee664 100644 --- a/uppsrc/CtrlCore/CtrlDraw.cpp +++ b/uppsrc/CtrlCore/CtrlDraw.cpp @@ -504,8 +504,14 @@ void Ctrl::UpdateArea0(SystemDraw& draw, const Rect& clip, int backpaint) LTIMING("UpdateArea"); LLOG("========== UPDATE AREA " << UPP::Name(this) << ", clip: " << clip << " =========="); ExcludeDHCtrls(draw, GetRect().GetSize(), clip); + auto DoCtrlPaint = [&](SystemDraw& w, const Rect& clip) { + CtrlPaint(w, clip); + #ifdef PLATFORM_WIN32 + PaintWinBar(w, clip); + #endif + }; if(globalbackbuffer) { - CtrlPaint(draw, clip); + DoCtrlPaint(draw, clip); LLOG("========== END (TARGET IS BACKBUFFER)"); return; } @@ -515,35 +521,12 @@ void Ctrl::UpdateArea0(SystemDraw& draw, const Rect& clip, int backpaint) bw.Create(draw, clip.GetSize()); bw.Offset(-clip.TopLeft()); bw.SetPaintingDraw(draw, clip.TopLeft()); - CtrlPaint(bw, clip); + DoCtrlPaint(bw, clip); bw.Put(draw, clip.TopLeft()); LLOG("========== END (FULLBACKPAINT)"); return; } -/* if(backpaint == TRANSPARENTBACKPAINT) { - LLOG("TransparentBackpaint"); - Vector area; - GatherTransparentAreas(area, draw, GetRect().GetSize(), clip); - for(int i = 0; i < area.GetCount(); i++) { - Rect ar = area[i]; - LLOG("Painting area: " << ar); - ShowRepaintRect(draw, ar, LtBlue()); - BackDraw bw; - bw.Create(draw, ar.GetSize()); - bw.Offset(-ar.TopLeft()); - bw.SetPaintingDraw(draw, ar.TopLeft()); - CtrlPaint(bw, ar); - bw.Put(draw, ar.TopLeft()); - if(!draw.ExcludeClip(ar)) { - LLOG("========== END"); - return; - } - } - PaintOpaqueAreas(draw, GetRect().GetSize(), clip); - LLOG("========== END"); - return; - }*/ - CtrlPaint(draw, clip); + DoCtrlPaint(draw, clip); LLOG("========== END"); } diff --git a/uppsrc/CtrlCore/TopWindow.cpp b/uppsrc/CtrlCore/TopWindow.cpp index 698589d6c..162dcf684 100644 --- a/uppsrc/CtrlCore/TopWindow.cpp +++ b/uppsrc/CtrlCore/TopWindow.cpp @@ -421,6 +421,34 @@ TopWindow& TopWindow::Icon(const Image& smallicon, const Image& _largeicon) return *this; } +bool is_custom_titlebar_available__; + +bool TopWindow::IsCustomTitleBarAvailable() +{ + return is_custom_titlebar_available__; +} + +TopWindow& TopWindow::CustomTitleBar(int cy) +{ + custom_titlebar = true; + custom_titlebar_cy = cy; + return *this; +} + +bool TopWindow::IsCustomTitleBarDragArea(Point p) +{ + DDUMP(p); + p += GetScreenRect().TopLeft(); // to handle frame widgets correctly + DDUMP(p); + for(Ctrl& q : *this) { + DDUMP(q.GetScreenRect()); + DDUMP(q.GetScreenRect().Contains(p)); + if(q.GetScreenRect().Contains(p)) + return false; + } + return true; +} + TopWindow& TopWindow::ToolWindow(bool b) { tool = b; @@ -505,6 +533,8 @@ TopWindow::TopWindow() dokeys = true; fullscreen = frameless = urgent = false; close_rejects = false; + custom_titlebar = false; + custom_titlebar_cy = 0; } TopWindow::~TopWindow() diff --git a/uppsrc/CtrlCore/TopWindow.h b/uppsrc/CtrlCore/TopWindow.h index 3bcc6e56a..6cb123ed1 100644 --- a/uppsrc/CtrlCore/TopWindow.h +++ b/uppsrc/CtrlCore/TopWindow.h @@ -17,6 +17,7 @@ public: virtual String GetDesc() const; virtual void ChildGotFocus(); virtual void SetMinSize(Size sz); + virtual bool IsCustomTitleBarDragArea(Point p); public: struct TopStyle : ChStyle { @@ -79,9 +80,14 @@ private: bool frameless:1; bool urgent:1; bool close_rejects:1; + bool custom_titlebar:1; byte state; Image icon, largeicon; + int custom_titlebar_cy = 0; + int active_titlebar_button = -1; + bool active_titlebar_active = false; + const TopStyle *st; void GuiPlatformConstruct(); @@ -174,6 +180,10 @@ public: TopWindow& Icon(const Image& m); TopWindow& LargeIcon(const Image& m); TopWindow& Icon(const Image& smallicon, const Image& largeicon); + + static bool IsCustomTitleBarAvailable(); + TopWindow& CustomTitleBar(int cy = 0); + bool IsCustomTitleBar() const { return custom_titlebar && IsCustomTitleBarAvailable(); } static const TopStyle& StyleDefault(); TopWindow& SetStyle(const TopStyle& s); diff --git a/uppsrc/CtrlCore/Win32Ctrl.h b/uppsrc/CtrlCore/Win32Ctrl.h index 0cd15a4e2..160cdf174 100644 --- a/uppsrc/CtrlCore/Win32Ctrl.h +++ b/uppsrc/CtrlCore/Win32Ctrl.h @@ -44,6 +44,8 @@ protected: void Create0(CreateBox *cr); void Create(HWND parent, DWORD style, DWORD exstyle, bool savebits, int show, bool dropshadow); Image DoMouse(int e, Point p, int zd = 0); + void PaintWinBar(SystemDraw& w, const Rect& clip); + int GetActiveTitleBarButton(); static void sProcessMSG(MSG& msg); static Vector > hotkey; diff --git a/uppsrc/CtrlCore/Win32Proc.cpp b/uppsrc/CtrlCore/Win32Proc.cpp index 88b6c025d..e9f42c5c3 100644 --- a/uppsrc/CtrlCore/Win32Proc.cpp +++ b/uppsrc/CtrlCore/Win32Proc.cpp @@ -82,6 +82,84 @@ void Ctrl::DoCancelPreedit() } } +static UINT getDpiForWindow(HWND hwnd) +{ + static UINT (WINAPI *GetDpiForWindow)(HWND hwnd); + DllFn(GetDpiForWindow, "user32.dll", "GetDpiForWindow"); + return GetDpiForWindow ? GetDpiForWindow(hwnd) : 96; +} + +static int getSystemMetricsForDpi(int nIndex, UINT dpi) +{ + static int (*GetSystemMetricsForDpi)(int nIndex, UINT dpi); + DllFn(GetSystemMetricsForDpi, "user32.dll", "GetSystemMetricsForDpi"); + return GetSystemMetricsForDpi ? GetSystemMetricsForDpi(nIndex, dpi) : 0; +} + +static bool IsMaximized(HWND hwnd) +{ + WINDOWPLACEMENT placement = {0}; + placement.length = sizeof(WINDOWPLACEMENT); + return GetWindowPlacement(hwnd, &placement) && placement.showCmd == SW_SHOWMAXIMIZED; +} + +static int win32_dpi_scale(int value, UINT dpi) +{ + return (int)((double)value * dpi / 96); +} + +static int getTitlebarButtonWidth(int dpi) +{ + return win32_dpi_scale(47, dpi); +} + +int GetWin32TitleBarHeight(HWND hwnd); // implemented in CtrlLib/ChWin32.cpp + +static Rect getTitleBarRect(HWND hwnd) // TODO (image, cy) +{ // Adopted from: https://github.com/oberth/custom-chrome/blob/master/source/gui/window_helper.hpp#L52-L64 + const int top_and_bottom_borders = 2; + + int height = win32_dpi_scale(GetWin32TitleBarHeight(hwnd), GetDpiForWindow(hwnd)) + top_and_bottom_borders; + + RECT rect; + GetClientRect(hwnd, &rect); + rect.bottom = rect.top + height; + return rect; +} + +void Ctrl::PaintWinBar(SystemDraw& w, const Rect& clip) +{ + bool custom_titlebar = false; + auto topwin = dynamic_cast(this); + HWND hwnd = GetHWND(); + if(topwin && topwin->custom_titlebar && hwnd) { + Rect r = getTitleBarRect(hwnd); +// draw.DrawRect(r, Yellow()); + int button_width = getTitlebarButtonWidth(GetDpiForWindow(hwnd)); + + int x = r.right; + int n = 0; + auto Drw = [&](const Image& m) { + x -= button_width; + Color ink = topwin->HasFocusDeep() ? SBlack() : Gray(); + if(topwin->active_titlebar_button == n) { + w.DrawRect(x, r.top, button_width, r.GetHeight(), n ? SWhiteGray() : Color(196, 43, 28)); + if(n == 0) + ink = SWhite(); + } + w.DrawImage(x + (button_width - m.GetWidth()) / 2, r.top + (r.GetHeight() - m.GetHeight()) / 2, m, ink); + n++; + }; + Drw(CtrlCoreImg::WinClose()); + if(topwin->IsZoomable()) { + Drw(IsMaximized(hwnd) ? CtrlCoreImg::WinMaximized() : CtrlCoreImg::WinMaximize()); + Drw(CtrlCoreImg::WinMinimize()); + } + + // TODO: Fake shadow rect? + } +} + LRESULT Ctrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { GuiLock __; eventid++; @@ -89,14 +167,46 @@ LRESULT Ctrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { Ptr _this = this; HWND hwnd = GetHWND(); + POINT p; + if(::GetCursorPos(&p)) + CurrentMousePos = p; + + bool custom_titlebar = false; + auto topwin = dynamic_cast(this); + if(topwin) + custom_titlebar = topwin->custom_titlebar; + + Rect titlebar_rect = Null; + int titlebar_button_width = 0; + int active_titlebar_button = -1; + bool active_titlebar_active = false; + + if(custom_titlebar) { + titlebar_rect = getTitleBarRect(hwnd); + titlebar_button_width = getTitlebarButtonWidth(GetDpiForWindow(hwnd)); + + Point p = CurrentMousePos; + ScreenToClient(hwnd, p); + if(p.y >= titlebar_rect.top && p.y < titlebar_rect.bottom) { + int q = (titlebar_rect.right - p.x) / titlebar_button_width; + active_titlebar_button = q >= 0 && q < (topwin->IsZoomable() ? 3 : 1) ? q : -1; + } + + active_titlebar_active = topwin->HasFocusDeep(); + + if(findarg(message, WM_PAINT, WM_NCPAINT) < 0 && + active_titlebar_button != topwin->active_titlebar_button || + active_titlebar_active != topwin->active_titlebar_active) { + topwin->active_titlebar_button = active_titlebar_button; + topwin->active_titlebar_active = active_titlebar_active; + InvalidateRect(hwnd, titlebar_rect, FALSE); + } + } + cancel_preedit = DoCancelPreedit; // We really need this just once, but whatever.. is_pen_event = (GetMessageExtraInfo() & 0xFFFFFF80) == 0xFF515700; // https://learn.microsoft.com/en-us/windows/win32/tablet/system-events-and-mouse-messages?redirectedfrom=MSDN - POINT p; - if(::GetCursorPos(&p)) - CurrentMousePos = p; - auto MousePos = [&] { Point p = Point((dword)lParam); CurrentMousePos = p; @@ -265,18 +375,102 @@ LRESULT Ctrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { } painting = true; UpdateArea(draw, Rect(ps.rcPaint)); - painting = false; if(draw.PaletteMode() && SystemDraw::AutoPalette()) SelectPalette(dc, hOldPal, TRUE); + painting = false; } EndPaint(hwnd, &ps); UpdateDHCtrls(); // so that they are displayed withing the same WM_PAINT - looks better } return 0L; - case WM_NCHITTEST: + case WM_NCCALCSIZE: + if(custom_titlebar && wParam) { // custom titlebar based on https://github.com/grassator/win32-window-custom-titlebar/blob/main/main.c + UINT dpi = GetDpiForWindow(hwnd); + + int frame_x = GetSystemMetricsForDpi(SM_CXFRAME, dpi); + int frame_y = GetSystemMetricsForDpi(SM_CYFRAME, dpi); + int padding = GetSystemMetricsForDpi(92 /*SM_CXPADDEDBORDER*/, dpi); + + NCCALCSIZE_PARAMS *params = (NCCALCSIZE_PARAMS *)lParam; + RECT *requested_client_rect = params->rgrc; + + requested_client_rect->right -= frame_x + padding; + requested_client_rect->left += frame_x + padding; + requested_client_rect->bottom -= frame_y + padding; + + if(IsMaximized(hwnd)) + requested_client_rect->top += padding; + + return 0; + } + break; + case WM_NCHITTEST: CheckMouseCtrl(); if(ignoremouse) return HTTRANSPARENT; + if(custom_titlebar) { + LRESULT hit = DefWindowProc(hwnd, message, wParam, lParam); + if(findarg(hit, HTNOWHERE, HTRIGHT, HTLEFT, HTTOPLEFT, HTTOP, + HTTOPRIGHT, HTBOTTOMRIGHT, HTBOTTOM, HTBOTTOMLEFT) >= 0) + return hit; + if(active_titlebar_button == 1) + return HTMAXBUTTON; + // Looks like adjustment happening in NCCALCSIZE is messing with the detection + // of the top hit area so manually fixing that. + UINT dpi = GetDpiForWindow(hwnd); + int frame_y = GetSystemMetricsForDpi(SM_CYFRAME, dpi); + int padding = GetSystemMetricsForDpi(92 /*SM_CXPADDEDBORDER*/, dpi); + Point cursor_point((LONG)lParam); + ScreenToClient(hwnd, cursor_point); + // We should not return HTTOP when hit-testing a maximized window + if(!IsMaximized(hwnd) && cursor_point.y > 0 && cursor_point.y < frame_y + padding && topwin->IsSizeable()) + return HTTOP; + + // Since we are drawing our own caption, this needs to be a custom test + if(cursor_point.y < getTitleBarRect(hwnd).bottom && topwin->IsCustomTitleBarDragArea(cursor_point)) + return HTCAPTION; + + return HTCLIENT; + } + break; + case WM_NCLBUTTONUP: // Map button clicks to the right messages for the window + switch(active_titlebar_button) { + case 0: + PostMessageW(hwnd, WM_CLOSE, 0, 0); + return 0; + case 1: + ShowWindow(hwnd, IsMaximized(hwnd) ? SW_NORMAL : SW_MAXIMIZE); + return 0; + case 2: + ShowWindow(hwnd, SW_MINIMIZE); + return 0; + } + break; + case WM_NCRBUTTONUP: + if(wParam == HTCAPTION) { + BOOL isMaximized = IsMaximized(hwnd); + MENUITEMINFO menu_item_info; + menu_item_info.cbSize = sizeof(menu_item_info); + menu_item_info.fMask = MIIM_STATE; + HMENU sys_menu = GetSystemMenu(hwnd, false); + + auto Menu = [&](UINT item, bool enabled) { + menu_item_info.fState = enabled ? MF_ENABLED : MF_DISABLED; + SetMenuItemInfo(sys_menu, item, false, &menu_item_info); + }; + + Menu(SC_RESTORE, isMaximized); + Menu(SC_MOVE, !isMaximized); + Menu(SC_SIZE, !isMaximized); + Menu(SC_MINIMIZE, true); + Menu(SC_MAXIMIZE, !isMaximized); + Menu(SC_CLOSE, true); + + Point p((LONG)lParam); + BOOL result = TrackPopupMenu(sys_menu, TPM_RETURNCMD, p.x, p.y, 0, hwnd, NULL); + if(result) + PostMessage(hwnd, WM_SYSCOMMAND, result, 0); + } break; case WM_LBUTTONDOWN: ClickActivate(); @@ -336,6 +530,11 @@ LRESULT Ctrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { if(_this) PostInput(); return 0L; case WM_NCLBUTTONDOWN: + ClickActivate(); + IgnoreMouseUp(); + if(active_titlebar_button >= 0) + return 0; + break; case WM_NCRBUTTONDOWN: case WM_NCMBUTTONDOWN: ClickActivate(); diff --git a/uppsrc/CtrlCore/Win32Wnd.cpp b/uppsrc/CtrlCore/Win32Wnd.cpp index 024fa9329..99cd3cf42 100644 --- a/uppsrc/CtrlCore/Win32Wnd.cpp +++ b/uppsrc/CtrlCore/Win32Wnd.cpp @@ -231,6 +231,10 @@ void Ctrl::InitWin32(HINSTANCE hInstance) { GuiLock __; LLOG("InitWin32"); + + extern bool is_custom_titlebar_available__; + + is_custom_titlebar_available__ = IsWin11(); InstallPanicMessageBox(&Win32PanicMessageBox); // RLOGBLOCK("Ctrl::InitWin32"); diff --git a/uppsrc/CtrlLib/ChWin32.cpp b/uppsrc/CtrlLib/ChWin32.cpp index 4ce5ef6fc..48c7c96ed 100644 --- a/uppsrc/CtrlLib/ChWin32.cpp +++ b/uppsrc/CtrlLib/ChWin32.cpp @@ -61,6 +61,15 @@ static HANDLE xp_widget_handle[XP_COUNT]; static VectorMap xp_margin; static VectorMap xp_opaque; +int GetWin32TitleBarHeight(HWND hwnd) +{ + SIZE title_bar_size = {0}; + HTHEME theme = XpTheme().OpenThemeData(hwnd, L"WINDOW"); + XpTheme().GetThemePartSize(theme, NULL, WP_CAPTION, CS_ACTIVE, NULL, TS_TRUE, &title_bar_size); + XpTheme().CloseThemeData(theme); + return title_bar_size.cy; +} + void XpClear() { for(int i = 0; i < XP_COUNT; i++)