From 4193ef4f3fb0129645cd933952c9cd441b46d050 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20R=C4=99bacz?= Date: Tue, 6 Jan 2026 10:55:25 +0100 Subject: [PATCH 1/7] Ide: Fix codeproject search link. --- uppsrc/ide/OnlineSearch.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uppsrc/ide/OnlineSearch.cpp b/uppsrc/ide/OnlineSearch.cpp index b48805b53..770a01b3c 100644 --- a/uppsrc/ide/OnlineSearch.cpp +++ b/uppsrc/ide/OnlineSearch.cpp @@ -50,7 +50,7 @@ void SearchEnginesDefaultSetup() { "C++ reference", "https://en.cppreference.com/mwiki/index.php?search=%s" }, { "Wikipedia", "https://en.wikipedia.org/w/index.php?search=%s" }, { "GitHub", "https://github.com/search?q=%s" }, - { "CodeProject", "https://www.codeproject.com/search.aspx?q=%s" }, + { "CodeProject", "https://www.codeproject.com/search?q=%s" }, { "WolframAlpha", "https://www.wolframalpha.com/input/?i=%s" }, }; From 97284bfac0dff43c32cc4c0f55c85ade21c6b6d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20R=C4=99bacz?= Date: Wed, 7 Jan 2026 00:16:21 +0100 Subject: [PATCH 2/7] Ide, MacroManager: .cosmetics --- uppsrc/ide/MacroManager/MacroManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uppsrc/ide/MacroManager/MacroManager.cpp b/uppsrc/ide/MacroManager/MacroManager.cpp index 6827b2040..11df48ffa 100644 --- a/uppsrc/ide/MacroManager/MacroManager.cpp +++ b/uppsrc/ide/MacroManager/MacroManager.cpp @@ -15,7 +15,7 @@ MacroManagerWindow::MacroManagerWindow(const Workspace& wspc, const String& hlSt , globalMacrosChanged(false) { CtrlLayout(*this, t_("Macro Manager")); - Zoomable().Sizeable().MinimizeBox(false); + Zoomable().Sizeable(); globalTree.NoRoot(); localTree.NoRoot(); From 7321080d165b6281ece805800abcf8298357d64b Mon Sep 17 00:00:00 2001 From: Mirek Fidler Date: Thu, 8 Jan 2026 11:27:57 +0100 Subject: [PATCH 3/7] ide: In .log, Alt+J context jump now tries to find the source of log line in .cpp --- uppsrc/ide/Annotations.cpp | 2 +- uppsrc/ide/ContextGoto.cpp | 1 + uppsrc/ide/Log.cpp | 184 ++++++++++++++++++ .../ide/app.tpp/EditorBeginnerInfo_en-us.tpp | 2 +- .../ide/app.tpp/EditorBeginnerInfo_en-us.tppi | 10 +- uppsrc/ide/ide.h | 4 + uppsrc/ide/idebar.cpp | 4 +- uppsrc/ide/idetool.cpp | 65 ------- 8 files changed, 199 insertions(+), 73 deletions(-) diff --git a/uppsrc/ide/Annotations.cpp b/uppsrc/ide/Annotations.cpp index 707b684da..dbf78737d 100644 --- a/uppsrc/ide/Annotations.cpp +++ b/uppsrc/ide/Annotations.cpp @@ -40,7 +40,7 @@ bool AssistEditor::GetAnnotationRefs(Vector& tl, String& coderef, int q) int GetMatchLen(const char *s, const char *t) { int i = 0; - while(s[i] == t[i] && s[i]) + while(s[i] == t[i] && s[i] && t[i]) i++; return i; } diff --git a/uppsrc/ide/ContextGoto.cpp b/uppsrc/ide/ContextGoto.cpp index b3e89b5d8..7ef27a62f 100644 --- a/uppsrc/ide/ContextGoto.cpp +++ b/uppsrc/ide/ContextGoto.cpp @@ -263,6 +263,7 @@ bool Ide::GotoId(const String& ref_id, const String& name, Point ref_pos, int li void Ide::ContextGoto() { + if(FindLOG()) return; ContextGoto0(editor.GetCursor()); } diff --git a/uppsrc/ide/Log.cpp b/uppsrc/ide/Log.cpp index bded69599..9b918d866 100644 --- a/uppsrc/ide/Log.cpp +++ b/uppsrc/ide/Log.cpp @@ -52,3 +52,187 @@ void Ide::OpenLog(const String& logFilePath) EditFile(logFilePath); } + +bool Ide::IsInLogFile() +{ + return !designer && ToLower(editfile).EndsWith(".log"); +} + +bool Ide::FindLOG() +{ + if(!IsInLogFile()) + return false; + + Vector files = FindXFiles(3); + + int n = 0; + Progress pi; + struct LogLine : Moveable { + String text; + int priority; + String file; + int line; + }; + Vector logs; + for(String fn : files) { + if(pi.SetCanceled(n++, files.GetCount())) + break; + + if(GetFileLength(fn) < 10*1024*1024) { + String text = LoadFile(fn); + try { + CParser p(text); + bool ignore = false; + while(!p.IsEof()) { + CParser::Pos pos = p.GetPos(); + int priority = 1; + auto AddLogLine = [&](const String& text) { + auto& l = logs.Add(); + l.text = text; + l.file = fn; + l.line = pos.line; + l.priority = priority; + }; + auto SkipLogBody0 = [&] { + int lvl = 1; + while(!p.IsEof()) + if(p.Char('(')) + lvl++; + else + if(p.Char(')')) { + if(--lvl == 0) + break; + } + else + p.Skip(); + }; + auto SkipLogBody = [&] { + if(!p.Char('(')) + return; + SkipLogBody0(); + }; + priority = p.IsId("DLOG") || p.IsId("DDUMP") || p.IsId("DTIMING") || p.IsId("DTIMESTOP") ? 2 : + p.IsId("LLOG") || p.IsId("LDUMP") || p.IsId("LTIMING") || p.IsId("LTIMESTOP") ? 0 : 1; + if(p.Char('#')) + p.SkipLine(); + else + if(p.Id("TIMING") || p.Id("DTIMING") || p.Id("RTIMING") || p.Id("LTIMING")) { + p.Char('('); + if(p.IsString()) + AddLogLine("TIMING " + p.ReadString()); + SkipLogBody0(); + } + if(p.Id("LOG") || p.Id("DLOG") || p.Id("RLOG") || p.Id("LLOG") || + p.Id("TIMESTOP") || p.Id("DTIMESTOP") || p.Id("RTIMESTOP") || p.Id("LTIMESTOP")) { + p.Char('('); + if(p.IsString()) + AddLogLine(p.ReadString()); + SkipLogBody0(); + } + else + if(p.Id("DUMP") || p.Id("DDUMP") || p.Id("RDUMP") || p.Id("LDUMP")) { + if(p.IsString()) { + AddLogLine(p.ReadString()); + SkipLogBody(); + } + else { + const char *b = p.GetPtr(); + SkipLogBody(); + String text = String(b, p.GetPtr()); + text = TrimBoth(text); + text.TrimStart("("); + text.TrimEnd(")"); + AddLogLine(TrimBoth(text) + " = "); + } + } + else + p.Skip(); + } + } + catch(CParser::Error) {} + } + } + + String ln = editor.GetUtf8Line(editor.GetCursorLine()); + + LogLine bestl; + int best = -1; + int bestp = false; + for(const LogLine& l : logs) { + int ml = GetMatchLen(l.text, ln); + if(ml > best || ml == best && l.priority > bestp) { + best = ml; + bestp = l.priority; + bestl = l; + } + } + + if(bestl.file.GetCount()) { + EditFile(bestl.file); + editor.SetCursor(editor.GetPos(bestl.line - 1, 0)); + } + return true; +} + +void Ide::FindDs(int where, bool all) +{ + SaveFile(); + + Vector files = FindXFiles(where); + + NewFFound(); + + int n = 0; + Progress pi; + for(String fn : files) { + if(pi.SetCanceled(n++, files.GetCount())) + break; + + if(GetFileLength(fn) < 10*1024*1024) { + String text = LoadFile(fn); + try { + CParser p(text); + bool ignore = false; + while(!p.IsEof()) { + CParser::Pos pos = p.GetPos(); + if(p.Char('#')) { + if(!all) { + if(p.Id("if") || p.Id("ifdef")) + ignore = true; + else + if(p.Id("endif")) + ignore = false; + } + p.SkipLine(); + } + else + if(p.IsId()) { + static Index ds = { + "DLOG", "DDUMP", "DDUMPC", "DDUMPM", "DTIMING", + "DLOGHEX", "DDUMPHEX", "DTIMESTOP", "DHITCOUNT" + }; + static Index ds_all = { + "DLOG", "DDUMP", "DDUMPC", "DDUMPM", "DTIMING", + "DLOGHEX", "DDUMPHEX", "DTIMESTOP", "DHITCOUNT", + "RLOG", "RDUMP", "RDUMPC", "RDUMPM", "RTIMING", + "RLOGHEX", "RDUMPHEX", "RTIMESTOP", "RHITCOUNT", + "LOG", "DUMP", "DUMPC", "DUMPM", "TIMING", + "LOGHEX", "DUMPHEX", "TIMESTOP", "HITCOUNT", + }; + String id = p.ReadId(); + if((all ? ds_all : ds).Find(id) >= 0 && p.Char('(') && !ignore) { + String line; + for(const char *s = pos.lineptr; findarg(*s, '\0', '\r', '\n') < 0; s++) + line.Cat(*s); + AddFoundFile(fn, pos.line, line, pos.ptr - pos.lineptr, id.GetCount()); + } + } + else + p.Skip(); + } + } + catch(CParser::Error) {} + } + } + FFoundFinish(); +} diff --git a/uppsrc/ide/app.tpp/EditorBeginnerInfo_en-us.tpp b/uppsrc/ide/app.tpp/EditorBeginnerInfo_en-us.tpp index d070fe47d..b83b24598 100644 --- a/uppsrc/ide/app.tpp/EditorBeginnerInfo_en-us.tpp +++ b/uppsrc/ide/app.tpp/EditorBeginnerInfo_en-us.tpp @@ -31,5 +31,5 @@ to beginning.]&] / rectangular selection.]&] [s0; [2 @@image:120&120/25 -(BGAAYAAAAAAAAAAAAHic7dXRasMwEERR//9Pt5BicMCksSzrzu7MBT1bOhPabUsppfShn8GTrjdqnU3Ge9o8W5xHuTvvQFu7bkG7Ou9AW7puQPs570CbuW5AOznvQNs4b0CbOG/w+HuvtuJO0xXHkjGH9iCTNl+4BVE594d3WFl5+8IbtHA/NvNNj8r/1cp+b9a7Yj+e+Abt/u6cJbyBjP3T3xD0l7Bf+T2hDfC/O8R3J75bwp+yF9gAt4ffP3yHid+Ov7G/gj28AWYf/+ENOrxZ6S6I/YhFU/8rGyzxJ0784x97zP+bDXCn+Pc7IvaW/qPFv539f/64l4L9w/6fNsDNDOzb+98t/oz7IvuW/oXs2/kXs2/lX9C+jX9R+xb+he3L+xe3t/en71/Zv7h7af8m9nb+9L0v+EtvYGAv62/y22/lT985/vy9Xf3p+97wl9ygif+30feMv9gx85fboIH/1ej7uvvLbVD4jEbfu8sZjb53l3Mn+u7Vz93o+79O4f+/M6LfUNV/ZvHn7Df6PfF/FX/Ofi/+nP1GvSv+b8Wfs9+LP2e/F3/Ofs/dXyFXf6VW/uYUjmK0ibP9Hm3jbH+MdnJ1P0abOdsfo/1c3Y/Rls72x2hXV/ezaGtH87PirlPM9Yp1SilN7hdqysBI) +(BGAAYABgAAAAAAAAAHic7dVBcoMwEERR38A3y/1vk6yo0oIkICP9nunuKtaI98F+vbIsy7Lf9n5/fc9c9LkrbtY6Tea32jwtzke5O3egrV1b0K7OHWhL1wa0n3MH2sy1Ae3k3IG2cW5Amzg32PG8d+fSQMmc6NHNfsc6NKjovrJD7D0adHEfV6lBN/tjFfy72h9TbtDxd+dsqg2U7FffQ81fxX7n/VQaKPzuEPd96plV/Cl7uoGCPf0Ozp6B/gbi38NfwZ5skHe/3jfQ4ZmVzkLZz1h09L/TYJc/ccU//rFn/K80oI3izzt1tXf1n138e9n/509bqdiv9P+rAe3lYO/g/+niz7jvsO/qX8W+o38l+27+1ew7+Ve07+Jf1b6Df2X7+LP21f0ru1f372Dv6E+f+6q/eoPu9sr+Du9+N3/6zPHnz+3qT5931l+1QQf/K/bxj7+7v2KD6v537OPP+ys2qHrN2Mc//l2uWf80YO2V/Kv+/37qr9Kgov8T9ioNqvk/aR9/3p9uUMl/hT3doIr/Svv48/5Ugwr+O+ypBur+O+2JBsr+hP3uBqr+pP0xV3/afdyu903lor3PRps42x+jbZztx9FOru7jaDNn+3G0n6v7ONrS2X4c7erqfjba2tH8bHHXWcz1Fussy7Ln9wNp6m8/) ][2 for more tips]]] \ No newline at end of file diff --git a/uppsrc/ide/app.tpp/EditorBeginnerInfo_en-us.tppi b/uppsrc/ide/app.tpp/EditorBeginnerInfo_en-us.tppi index c0e1531c0..a0459714c 100644 --- a/uppsrc/ide/app.tpp/EditorBeginnerInfo_en-us.tppi +++ b/uppsrc/ide/app.tpp/EditorBeginnerInfo_en-us.tppi @@ -1,8 +1,8 @@ TITLE("Ctrl+Tab - cycle through files") COMPRESSED -120,156,141,85,105,147,155,56,16,253,43,170,74,54,149,68,179,17,183,96,242,37,190,153,89,31,196,199,216,142,203,181,65,70,50,242,96,96,64,224,99,107,255,251,202,246,204,58,187,137,157,80,101,23,84,119,191,247,212,253,26,102,174,241,145,216,250,199,247,6,120,253,90,189,81,94,41,216,182,12,213,192,134,97,106,58,54,13,67,83,12,67,85,229,189,106,98,11,227,91,193,69,68,231,179,99,17,84,85,44,235,180,27,237,149,106,26,86,77,171,213,15,185,213,74,85,169,104,86,205,212,141,186,213,84,213,70,93,213,111,243,130,60,151,202,10,229,192,244,147,235,182,78,153,95,68,98,62,251,235,207,191,127,107,116,127,31,13,192,44,87,62,130,217,251,79,111,149,15,202,7,205,52,223,105,160,38,178,232,43,28,250,100,62,211,0,168,237,22,17,5,140,71,52,255,48,127,51,255,65,126,35,95,128,67,234,32,76,54,40,228,1,5,36,17,34,89,131,212,143,233,133,154,74,36,190,194,54,101,226,200,129,100,253,247,225,62,95,134,167,120,43,1,196,95,60, -34,150,100,27,63,11,46,96,158,116,127,157,253,24,242,57,58,63,70,187,116,43,100,74,154,209,146,39,69,14,214,190,88,132,60,94,2,146,73,30,42,174,50,92,150,125,138,159,117,123,47,248,8,196,7,198,77,242,19,241,181,83,203,147,116,7,114,26,209,133,224,73,12,56,3,126,188,187,145,100,72,3,139,34,203,104,44,64,196,99,122,76,78,68,72,179,13,207,47,117,250,4,60,61,78,40,201,126,172,184,125,162,45,196,127,224,47,0,190,24,227,187,211,15,66,206,196,217,56,227,144,198,223,158,34,7,1,101,18,54,184,1,60,14,14,36,231,96,118,104,153,68,140,100,107,47,208,62,163,159,4,143,210,171,18,78,73,245,100,19,31,211,58,73,73,143,39,66,103,198,34,69,129,140,95,109,218,37,150,255,193,15,22,89,18,69,47,136,215,0,61,127,73,159,65,223,94,154,133,155,172,143,131,125,119,112,189,144,198,167,75,30,131,132,1,57,231,227,26,94,149,124,96,248,87,216,69,142,70,28,124,75,65,227,224,151,9,234,178,131,226,228,188,211,45,224, -135,89,114,198,105,6,88,38,183,94,90,40,151,196,39,220,171,88,85,185,107,121,234,47,126,17,238,216,137,88,110,233,181,119,202,179,3,70,41,58,180,1,29,118,21,157,23,178,35,223,126,252,224,132,23,88,4,50,105,8,63,94,22,145,159,157,13,121,102,208,192,167,79,124,45,187,122,171,106,202,27,249,67,154,249,182,218,170,84,166,149,111,46,151,47,112,48,233,251,121,103,211,104,244,251,8,57,158,48,171,124,209,169,61,230,131,125,182,47,112,167,58,84,73,47,244,124,50,202,211,148,13,194,216,110,13,179,85,240,20,143,244,22,117,18,123,108,110,221,98,88,150,159,155,5,38,143,45,220,43,156,202,24,167,197,103,47,55,177,82,35,197,216,172,244,246,113,249,185,155,27,68,62,247,90,104,3,221,162,20,197,125,79,217,78,220,199,85,203,117,120,109,216,141,160,81,125,104,152,142,17,232,227,102,100,66,251,142,8,183,130,186,101,183,187,178,51,164,46,82,72,28,31,79,87,144,194,10,17,168,176,22,247,100,87,93,121,250,80,223,214,149,8,87,25,28, -106,97,157,213,80,207,238,235,247,216,36,155,20,238,154,206,178,34,12,198,60,125,231,242,0,246,74,220,66,203,149,102,87,198,83,134,96,163,219,203,182,95,172,129,117,135,166,97,115,132,236,172,181,219,111,239,229,183,207,216,58,120,239,65,82,159,212,98,232,45,240,93,233,143,209,147,215,44,77,221,97,200,50,34,163,237,108,144,197,186,121,189,91,239,237,9,116,108,129,146,189,204,43,198,40,153,228,26,122,60,252,69,19,167,6,87,19,167,15,183,4,134,84,111,195,45,213,5,162,49,86,209,151,18,135,216,103,246,218,137,101,121,91,41,97,67,148,211,86,165,180,52,180,211,100,237,208,177,77,84,238,156,9,211,83,232,224,77,228,236,150,156,65,93,97,180,83,58,203,173,109,50,146,220,185,72,165,43,92,148,101,155,60,212,141,85,131,176,194,206,191,172,136,169,71,122,39,134,5,126,216,59,122,2,177,211,51,24,68,29,171,205,70,221,7,73,238,198,184,206,44,143,53,81,115,130,122,140,35,24,123,106,171,28,148,144,216,99,150,59,176,237,105,20,53,117, -25,203,81,48,217,53,39,204,122,24,163,98,58,90,173,255,80,56,241,28,119,173,175,136,11,59,65,124,175,122,138,79,122,65,206,18,57,41,125,138,250,81,142,181,173,22,78,30,16,221,251,45,225,218,216,227,89,228,117,156,105,170,14,120,212,197,97,240,180,203,171,119,239,142,6,151,95,72,176,78,50,10,4,79,243,249,124,254,15,22,172,141,161, +120,156,141,85,105,111,219,56,16,253,43,4,122,160,45,179,165,68,74,162,148,126,169,207,56,241,165,196,177,115,24,198,86,7,105,203,150,69,153,58,124,44,246,191,175,100,39,235,238,182,118,43,64,144,128,153,121,239,113,230,141,52,110,105,95,92,147,124,249,164,129,183,111,213,11,229,141,66,77,67,83,53,170,105,58,38,84,215,52,172,104,154,170,22,239,170,78,13,74,47,211,32,13,217,100,188,47,130,170,74,139,58,124,129,223,168,186,102,212,112,173,94,230,86,43,85,165,130,141,154,78,180,186,209,84,213,70,93,37,151,73,230,190,148,22,21,74,201,244,139,235,178,206,184,147,133,233,100,252,215,159,127,191,107,244,254,24,14,192,56,81,190,128,241,167,175,31,148,207,202,103,172,235,31,49,168,165,50,252,6,239,29,119,50,198,0,212,182,94,200,0,15,66,150,124,158,188,159,252,36,191,145,120,160,76,29,204,196,26,205,2,159,1,87,164,169,88,130,216,137,216,137,154,74,152,126,131,29,198,211,61,7,42,234,127,12,223,5,211,217,33,126,37,128,235,120, +11,196,133,92,59,210,63,129,121,208,253,109,252,115,200,151,232,100,31,237,177,77,90,164,196,146,229,129,200,18,176,116,82,111,22,68,83,224,202,130,135,165,103,25,78,203,62,196,143,186,237,87,124,4,162,146,113,45,126,33,190,118,104,185,136,183,32,97,33,243,210,64,68,32,224,192,137,182,23,5,25,194,192,203,164,100,81,10,194,32,98,251,100,145,206,152,92,7,201,169,78,31,128,159,246,19,18,242,231,138,59,7,218,44,253,15,252,9,192,87,99,252,112,250,193,44,224,233,209,56,15,51,22,125,127,138,4,248,140,23,176,254,5,8,34,191,36,57,6,101,217,178,2,49,44,90,123,130,246,5,253,32,120,24,159,149,112,72,170,139,117,180,79,235,138,156,237,79,132,142,140,89,140,252,34,126,182,105,167,88,254,7,63,240,164,8,195,87,196,115,128,182,51,101,47,160,31,78,205,162,37,150,251,193,126,44,93,159,22,198,103,211,32,2,130,131,98,206,251,53,60,43,185,100,248,87,216,73,142,70,228,127,79,193,34,255,183,9,234,69,7,211,131,243,14,175, +32,40,103,25,240,128,73,192,101,177,245,133,133,146,130,248,128,123,22,171,90,236,90,18,59,222,111,194,237,59,17,21,91,122,238,155,242,226,128,97,140,202,54,160,114,87,209,113,33,187,197,215,47,40,157,240,10,139,128,44,12,225,68,211,44,116,228,209,144,71,6,12,190,126,13,150,69,87,47,85,172,188,47,110,132,245,15,213,171,74,229,169,82,157,86,94,175,86,224,81,127,84,245,68,119,221,104,220,221,17,179,66,182,72,205,23,198,86,40,226,122,113,93,179,173,40,139,178,118,234,92,91,102,19,230,238,117,178,165,29,110,69,58,226,158,229,89,157,133,116,211,39,227,158,57,4,207,215,233,110,193,244,62,97,83,57,82,93,165,77,251,173,135,89,71,93,59,74,68,186,45,156,108,213,10,35,11,114,125,133,189,7,189,178,220,77,9,182,175,76,31,242,193,109,119,233,25,189,86,143,39,197,163,61,23,185,188,169,211,186,226,248,173,6,31,25,97,181,135,210,121,147,111,41,158,89,247,110,90,223,248,208,79,86,83,60,164,77,206,111,77,149,111,30,105,132, +70,183,78,219,222,101,13,219,183,140,56,28,161,90,72,51,113,85,179,185,210,223,197,70,21,77,221,128,152,61,190,126,214,147,69,139,33,50,231,183,218,243,114,180,91,116,158,119,234,76,177,58,232,254,233,198,67,158,55,68,72,54,35,212,54,139,22,144,96,183,75,213,244,145,171,145,74,76,102,69,72,87,44,119,229,7,185,101,67,89,156,39,124,234,163,41,130,81,176,163,243,60,233,163,213,163,249,0,5,49,67,136,41,84,217,154,194,17,83,40,188,225,170,107,212,57,126,164,176,99,99,149,43,50,83,57,161,184,158,27,13,200,161,177,66,76,216,153,149,72,88,207,44,216,35,200,216,217,173,104,7,201,234,94,183,136,26,66,245,246,150,163,54,114,55,115,10,105,142,219,117,35,215,9,237,219,54,220,38,120,213,146,61,220,245,16,10,113,246,192,77,229,169,143,71,168,157,67,68,232,74,90,237,169,200,205,123,43,16,189,85,190,64,206,157,133,72,108,101,195,110,136,102,247,196,23,215,18,13,242,92,51,145,62,156,174,37,236,195,109,92,205,202,39,190,169, +22,122,102,54,201,170,43,9,99,91,217,140,8,114,184,191,205,44,133,132,66,18,251,46,78,52,188,129,115,247,121,151,110,172,102,95,102,116,238,212,123,17,36,87,74,100,228,180,223,147,3,252,168,121,148,201,21,159,187,14,78,91,166,219,106,61,62,120,59,181,153,37,165,151,34,107,221,139,141,165,137,62,238,141,94,252,41,193,82,72,6,210,32,78,38,147,201,63,219,210,144,221, diff --git a/uppsrc/ide/ide.h b/uppsrc/ide/ide.h index 6da01dd4c..b3b29d5bf 100644 --- a/uppsrc/ide/ide.h +++ b/uppsrc/ide/ide.h @@ -292,6 +292,8 @@ struct EditorTabBar : public FileTabs { int memcmp_i(const char *s, const char *t, int n); +int GetMatchLen(const char *s, const char *t); + String ResolveTParam(const String& type, const Vector& tparam); void ResolveTParam(Vector& type, const Vector& tparam); String Qualify(const String& scope, const String& type, const String& usings); @@ -1081,6 +1083,8 @@ public: String GetTargetLogPath(); String GetIdeLogPath(); void OpenLog(const String& logFilePath); + bool IsInLogFile(); + bool FindLOG(); String include_path; // cached value of include path, GetIncludePath diff --git a/uppsrc/ide/idebar.cpp b/uppsrc/ide/idebar.cpp index 131772c42..8b4ecbde3 100644 --- a/uppsrc/ide/idebar.cpp +++ b/uppsrc/ide/idebar.cpp @@ -866,7 +866,9 @@ void Ide::AssistMenu(Bar& menu) { LTIMESTOP("AssistMenu"); menu.Add(!designer, AK_ASSIST, [=] { editor.Assist(true); }); - menu.Add(!designer, AK_JUMPS, [=] { ContextGoto(); }); + auto& m = menu.Add(!designer, AK_JUMPS, [=] { ContextGoto(); }); + if(IsInLogFile()) + m.Text("Try to find the source of log line"); menu.Add(!designer, AK_SWAPS, THISBACK(SwapS)); menu.Add(!designer, AK_DCOPY, callback(&editor, &AssistEditor::DCopy)); menu.Add(!designer, AK_IDUSAGE, THISBACK(IdUsage)); diff --git a/uppsrc/ide/idetool.cpp b/uppsrc/ide/idetool.cpp index e501a8bed..60c2565f9 100644 --- a/uppsrc/ide/idetool.cpp +++ b/uppsrc/ide/idetool.cpp @@ -557,69 +557,6 @@ Vector Ide::FindXFiles(int where) return files; } -void Ide::FindDs(int where, bool all) -{ - SaveFile(); - - Vector files = FindXFiles(where); - - NewFFound(); - - int n = 0; - Progress pi; - for(String fn : files) { - if(pi.SetCanceled(n++, files.GetCount())) - break; - - if(GetFileLength(fn) < 10*1024*1024) { - String text = LoadFile(fn); - try { - CParser p(text); - bool ignore = false; - while(!p.IsEof()) { - CParser::Pos pos = p.GetPos(); - if(p.Char('#')) { - if(!all) { - if(p.Id("if") || p.Id("ifdef")) - ignore = true; - else - if(p.Id("endif")) - ignore = false; - } - p.SkipLine(); - } - else - if(p.IsId()) { - static Index ds = { - "DLOG", "DDUMP", "DDUMPC", "DDUMPM", "DTIMING", - "DLOGHEX", "DDUMPHEX", "DTIMESTOP", "DHITCOUNT" - }; - static Index ds_all = { - "DLOG", "DDUMP", "DDUMPC", "DDUMPM", "DTIMING", - "DLOGHEX", "DDUMPHEX", "DTIMESTOP", "DHITCOUNT", - "RLOG", "RDUMP", "RDUMPC", "RDUMPM", "RTIMING", - "RLOGHEX", "RDUMPHEX", "RTIMESTOP", "RHITCOUNT", - "LOG", "DUMP", "DUMPC", "DUMPM", "TIMING", - "LOGHEX", "DUMPHEX", "TIMESTOP", "HITCOUNT", - }; - String id = p.ReadId(); - if((all ? ds_all : ds).Find(id) >= 0 && p.Char('(') && !ignore) { - String line; - for(const char *s = pos.lineptr; findarg(*s, '\0', '\r', '\n') < 0; s++) - line.Cat(*s); - AddFoundFile(fn, pos.line, line, pos.ptr - pos.lineptr, id.GetCount()); - } - } - else - p.Skip(); - } - } - catch(CParser::Error) {} - } - } - FFoundFinish(); -} - void Ide::FindGitConflicts() { SaveFile(); @@ -648,8 +585,6 @@ void Ide::FindGitConflicts() FFoundFinish(); } - - void Ide::CopyRich() { String qtf = "[C0 "; From dfd264cba6d42425316b91b69a4c9b707fc27bd5 Mon Sep 17 00:00:00 2001 From: Mirek Fidler Date: Thu, 8 Jan 2026 12:07:35 +0100 Subject: [PATCH 4/7] ide: log alt-j minor improvements --- uppsrc/ide/Log.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/uppsrc/ide/Log.cpp b/uppsrc/ide/Log.cpp index 9b918d866..81f3aa047 100644 --- a/uppsrc/ide/Log.cpp +++ b/uppsrc/ide/Log.cpp @@ -82,7 +82,6 @@ bool Ide::FindLOG() String text = LoadFile(fn); try { CParser p(text); - bool ignore = false; while(!p.IsEof()) { CParser::Pos pos = p.GetPos(); int priority = 1; @@ -168,8 +167,10 @@ bool Ide::FindLOG() } if(bestl.file.GetCount()) { + AddHistory(); EditFile(bestl.file); editor.SetCursor(editor.GetPos(bestl.line - 1, 0)); + AddHistory(); } return true; } From e6c0fc4f8ece29d3213a87a1276fbfc1befc1a92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20R=C4=99bacz?= Date: Thu, 8 Jan 2026 23:04:08 +0100 Subject: [PATCH 5/7] Reference: Events migrate to override plus fix HorzMouseWheel. --- reference/Events/Events.cpp | 79 +++++++++++++++++++------------------ 1 file changed, 40 insertions(+), 39 deletions(-) diff --git a/reference/Events/Events.cpp b/reference/Events/Events.cpp index ac36ebc48..29b67b17b 100644 --- a/reference/Events/Events.cpp +++ b/reference/Events/Events.cpp @@ -19,18 +19,18 @@ struct App : TopWindow { log.GoEnd(); } - virtual void Activate() + void Activate() override { Log("Activate"); SetFocus(); } - virtual void Deactivate() + void Deactivate() override { Log("Deactivate"); } - virtual Image FrameMouseEvent(int event, Point p, int zdelta, dword keyflags) + Image FrameMouseEvent(int event, Point p, int zdelta, dword keyflags) override { if(event != CURSORIMAGE) Log(Format("FrameMouseEvent(%d, Point(%d, %d), %d, %x)", @@ -38,7 +38,7 @@ struct App : TopWindow { return TopWindow::FrameMouseEvent(event, p, zdelta, keyflags); } - virtual Image MouseEvent(int event, Point p, int zdelta, dword keyflags) + Image MouseEvent(int event, Point p, int zdelta, dword keyflags) override { if(event != CURSORIMAGE) Log(Format("MouseEvent(%d, Point(%d, %d), %d, %x)", @@ -46,175 +46,176 @@ struct App : TopWindow { return TopWindow::MouseEvent(event, p, zdelta, keyflags); } - virtual void MouseEnter(Point p, dword keyflags) + void MouseEnter(Point p, dword keyflags) override { Log(Format("MouseEnter(Point(%d, %d), %x)", p.x, p.y, (int)keyflags)); } - virtual void MouseMove(Point p, dword keyflags) + void MouseMove(Point p, dword keyflags) override { Log(Format("MouseMove(Point(%d, %d), %x)", p.x, p.y, (int)keyflags)); } - virtual void LeftDown(Point p, dword keyflags) + void LeftDown(Point p, dword keyflags) override { Log(Format("LeftDown(Point(%d, %d), %x)", p.x, p.y, (int)keyflags)); SetFocus(); } - virtual void LeftDouble(Point p, dword keyflags) + void LeftDouble(Point p, dword keyflags) override { Log(Format("LeftDouble(Point(%d, %d), %x)", p.x, p.y, (int)keyflags)); } - virtual void LeftTriple(Point p, dword keyflags) + void LeftTriple(Point p, dword keyflags) override { Log(Format("LeftTriple(Point(%d, %d), %x)", p.x, p.y, (int)keyflags)); } - virtual void LeftDrag(Point p, dword keyflags) { + void LeftDrag(Point p, dword keyflags) override { Log(Format("LeftDrag(Point(%d, %d), %x)", p.x, p.y, (int)keyflags)); } - virtual void LeftHold(Point p, dword keyflags) { + void LeftHold(Point p, dword keyflags) override { Log(Format("LeftHold(Point(%d, %d), %x)", p.x, p.y, (int)keyflags)); } - virtual void LeftRepeat(Point p, dword keyflags) + void LeftRepeat(Point p, dword keyflags) override { Log(Format("LeftRepeat(Point(%d, %d), %x)", p.x, p.y, (int)keyflags)); } - virtual void LeftUp(Point p, dword keyflags) + void LeftUp(Point p, dword keyflags) override { Log(Format("LeftUp(Point(%d, %d), %x)", p.x, p.y, (int)keyflags)); } - virtual void RightDown(Point p, dword keyflags) + void RightDown(Point p, dword keyflags) override { Log(Format("RightDown(Point(%d, %d), %x)", p.x, p.y, (int)keyflags)); } - virtual void RightDouble(Point p, dword keyflags) + void RightDouble(Point p, dword keyflags) override { Log(Format("RightDouble(Point(%d, %d), %x)", p.x, p.y, (int)keyflags)); } - virtual void RightTriple(Point p, dword keyflags) + void RightTriple(Point p, dword keyflags) override { Log(Format("RightTriple(Point(%d, %d), %x)", p.x, p.y, (int)keyflags)); } - virtual void RightDrag(Point p, dword keyflags) { + void RightDrag(Point p, dword keyflags) override { Log(Format("RightDrag(Point(%d, %d), %x)", p.x, p.y, (int)keyflags)); } - virtual void RightHold(Point p, dword keyflags) { + void RightHold(Point p, dword keyflags) override { Log(Format("RightHold(Point(%d, %d), %x)", p.x, p.y, (int)keyflags)); } - virtual void RightRepeat(Point p, dword keyflags) + void RightRepeat(Point p, dword keyflags) override { Log(Format("RightRepeat(Point(%d, %d), %x)", p.x, p.y, (int)keyflags)); } - virtual void RightUp(Point p, dword keyflags) + void RightUp(Point p, dword keyflags) override { Log(Format("RightUp(Point(%d, %d), %x)", p.x, p.y, (int)keyflags)); } - virtual void MiddleDown(Point p, dword keyflags) + void MiddleDown(Point p, dword keyflags) override { Log(Format("MiddleDown(Point(%d, %d), %x)", p.x, p.y, (int)keyflags)); } - virtual void MiddleDouble(Point p, dword keyflags) + void MiddleDouble(Point p, dword keyflags) override { Log(Format("MiddleDouble(Point(%d, %d), %x)", p.x, p.y, (int)keyflags)); } - virtual void MiddleTriple(Point p, dword keyflags) + void MiddleTriple(Point p, dword keyflags) override { Log(Format("MiddleTriple(Point(%d, %d), %x)", p.x, p.y, (int)keyflags)); } - virtual void MiddleDrag(Point p, dword keyflags) { + void MiddleDrag(Point p, dword keyflags) override { Log(Format("MiddleDrag(Point(%d, %d), %x)", p.x, p.y, (int)keyflags)); } - virtual void MiddleHold(Point p, dword keyflags) { + void MiddleHold(Point p, dword keyflags) override { Log(Format("MiddleHold(Point(%d, %d), %x)", p.x, p.y, (int)keyflags)); } - virtual void MiddleRepeat(Point p, dword keyflags) + void MiddleRepeat(Point p, dword keyflags) override { Log(Format("MiddleRepeat(Point(%d, %d), %x)", p.x, p.y, (int)keyflags)); } - virtual void MiddleUp(Point p, dword keyflags) + void MiddleUp(Point p, dword keyflags) override { Log(Format("MiddleUp(Point(%d, %d), %x)", p.x, p.y, (int)keyflags)); } - virtual void MouseWheel(Point p, int zdelta, dword keyflags) + void MouseWheel(Point p, int zdelta, dword keyflags) override { Log(Format("MouseWheel(Point(%d, %d), %d, %x)", p.x, p.y, zdelta, (int)keyflags)); } - virtual void MouseWheelH(Point p, int zdelta, dword keyflags) + void HorzMouseWheel(Point p, int zdelta, dword keyflags) override { - Log(Format("MouseWheelH(Point(%d, %d), %d, %x)", p.x, p.y, zdelta, (int)keyflags)); + Log(Format("HorzMouseWheel(Point(%d, %d), %d, %x)", p.x, p.y, zdelta, (int)keyflags)); } - virtual void MouseLeave() + void MouseLeave() override { Log("MouseLeave"); } - virtual Image CursorImage(Point p, dword keyflags) + Image CursorImage(Point p, dword keyflags) override { return keyflags & K_CTRL ? CtrlImg::swap_color_cursor() : Image::Arrow(); } - virtual bool Key(dword key, int count) + bool Key(dword key, int count) override { Log(Format("Key(%x, %d) ", (int)key, count) + GetKeyDescEx(key)); return false; } - virtual void GotFocus() + void GotFocus() override { Log("GotFocus"); } - virtual void LostFocus() + void LostFocus() override { Log("LostFocus"); } - virtual bool HotKey(dword key) + bool HotKey(dword key) override { Log(Format("HotKey(%x) ", (int)key) + GetKeyDescEx(key)); return false; } - virtual void ChildGotFocus() + void ChildGotFocus() override { Log("ChildGotFocus"); } - virtual void ChildLostFocus() + void ChildLostFocus() override { Log("ChildLostFocus"); } - virtual void Layout() + void Layout() override { Log("Layout"); } App() { + Title("Events"); SetFrame(InsetFrame()); AddFrame(InsetFrame()); AddFrame(InsetFrame()); From 0ed253c70ca07c8c386e82cf47fae7f8a19b1fbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20R=C4=99bacz?= Date: Fri, 9 Jan 2026 00:28:03 +0100 Subject: [PATCH 6/7] CtrlLib, Doc: Added tutorial about using Key function to handle keyboard keys + alligning directory structure for tutorials. --- .../{Gui05/Gui05.upp => Gui05a/Gui05a.upp} | 0 tutorial/{Gui05 => Gui05a}/main.cpp | 3 +- .../{Gui07/Gui07.upp => Gui05b/Gui05b.upp} | 20 +++-- tutorial/Gui05b/main.cpp | 45 +++++++++++ tutorial/Gui07/main.cpp | 32 -------- tutorial/Gui07a/Gui07a.upp | 2 +- tutorial/Gui07a/main.cpp | 64 +++++++-------- tutorial/Gui07b/Gui07b.upp | 11 +++ tutorial/Gui07b/main.cpp | 32 ++++++++ uppsrc/CtrlLib/srcdoc.tpp/Tutorial_en-us.tpp | 81 +++++++++++++++++-- 10 files changed, 207 insertions(+), 83 deletions(-) rename tutorial/{Gui05/Gui05.upp => Gui05a/Gui05a.upp} (100%) rename tutorial/{Gui05 => Gui05a}/main.cpp (94%) rename tutorial/{Gui07/Gui07.upp => Gui05b/Gui05b.upp} (69%) create mode 100644 tutorial/Gui05b/main.cpp delete mode 100644 tutorial/Gui07/main.cpp create mode 100644 tutorial/Gui07b/Gui07b.upp create mode 100644 tutorial/Gui07b/main.cpp diff --git a/tutorial/Gui05/Gui05.upp b/tutorial/Gui05a/Gui05a.upp similarity index 100% rename from tutorial/Gui05/Gui05.upp rename to tutorial/Gui05a/Gui05a.upp diff --git a/tutorial/Gui05/main.cpp b/tutorial/Gui05a/main.cpp similarity index 94% rename from tutorial/Gui05/main.cpp rename to tutorial/Gui05a/main.cpp index aa09f1cd7..fd79a9e66 100644 --- a/tutorial/Gui05/main.cpp +++ b/tutorial/Gui05a/main.cpp @@ -29,6 +29,5 @@ struct MyAppWindow : TopWindow { GUI_APP_MAIN { - MyAppWindow app; - app.Run(); + MyAppWindow().Run(); } diff --git a/tutorial/Gui07/Gui07.upp b/tutorial/Gui05b/Gui05b.upp similarity index 69% rename from tutorial/Gui07/Gui07.upp rename to tutorial/Gui05b/Gui05b.upp index 9b8c16af3..5c4f53e15 100644 --- a/tutorial/Gui07/Gui07.upp +++ b/tutorial/Gui05b/Gui05b.upp @@ -1,11 +1,9 @@ -description "Menu\377"; - -uses - CtrlLib; - -file - main.cpp; - -mainconfig - "" = "GUI"; - +uses + CtrlLib; + +file + main.cpp; + +mainconfig + "" = "GUI"; + diff --git a/tutorial/Gui05b/main.cpp b/tutorial/Gui05b/main.cpp new file mode 100644 index 000000000..19eb2795a --- /dev/null +++ b/tutorial/Gui05b/main.cpp @@ -0,0 +1,45 @@ +#include + +using namespace Upp; + +struct MyAppWindow : TopWindow { + String text = "Press any arrow key..."; + + bool Key(dword key, int count) override { + switch(key) { + case K_UP: + text = "Up ⬆"; + Refresh(); + return true; + case K_DOWN: + text = "Down ⬇"; + Refresh(); + return true; + case K_LEFT: + text = "Left ⬅"; + Refresh(); + return true; + case K_RIGHT: + text = "Right ⮕"; + Refresh(); + return true; + default: + return TopWindow::Key(key, count); + } + } + + void Paint(Draw& w) override { + w.DrawRect(GetSize(), SWhite); + w.DrawText(45, 20, text, Arial(20), Magenta); + } + + MyAppWindow() { + Title("My application").Zoomable(); + SetRect(0, 0, 400, 100); + } +}; + +GUI_APP_MAIN +{ + MyAppWindow().Run(); +} diff --git a/tutorial/Gui07/main.cpp b/tutorial/Gui07/main.cpp deleted file mode 100644 index 9c8466ce8..000000000 --- a/tutorial/Gui07/main.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include - -using namespace Upp; - -struct MyAppWindow : TopWindow { - MenuBar menu; - - void Exit() { - if(PromptOKCancel("Exit MyApp?")) - Break(); - } - - void SubMenu(Bar& bar) { - bar.Add("Exit", [=] { Exit(); }); - } - - void MainMenu(Bar& bar) { - bar.Sub("Menu", [=](Bar& bar) { SubMenu(bar); }); - } - - MyAppWindow() { - Title("My application with menu").Sizeable(); - AddFrame(menu); - menu.Set([=](Bar& bar) { MainMenu(bar); }); - } -}; - -GUI_APP_MAIN -{ - MyAppWindow app; - app.Run(); -} diff --git a/tutorial/Gui07a/Gui07a.upp b/tutorial/Gui07a/Gui07a.upp index 7e42bf965..9b8c16af3 100644 --- a/tutorial/Gui07a/Gui07a.upp +++ b/tutorial/Gui07a/Gui07a.upp @@ -1,4 +1,4 @@ -description "Menu - as single lambda\377"; +description "Menu\377"; uses CtrlLib; diff --git a/tutorial/Gui07a/main.cpp b/tutorial/Gui07a/main.cpp index 93c045db2..9c8466ce8 100644 --- a/tutorial/Gui07a/main.cpp +++ b/tutorial/Gui07a/main.cpp @@ -1,32 +1,32 @@ -#include - -using namespace Upp; - -struct MyAppWindow : TopWindow { - MenuBar menu; - - MyAppWindow() { - Title("My application with menu").Sizeable(); - AddFrame(menu); - menu.Set( - [=](Bar& bar) { - bar.Sub("Menu", - [=](Bar& bar) { - bar.Add("Exit", - [=] { - if(PromptOKCancel("Exit MyApp?")) - Break(); - } - ); - } - ); - } - ); - } -}; - -GUI_APP_MAIN -{ - MyAppWindow app; - app.Run(); -} +#include + +using namespace Upp; + +struct MyAppWindow : TopWindow { + MenuBar menu; + + void Exit() { + if(PromptOKCancel("Exit MyApp?")) + Break(); + } + + void SubMenu(Bar& bar) { + bar.Add("Exit", [=] { Exit(); }); + } + + void MainMenu(Bar& bar) { + bar.Sub("Menu", [=](Bar& bar) { SubMenu(bar); }); + } + + MyAppWindow() { + Title("My application with menu").Sizeable(); + AddFrame(menu); + menu.Set([=](Bar& bar) { MainMenu(bar); }); + } +}; + +GUI_APP_MAIN +{ + MyAppWindow app; + app.Run(); +} diff --git a/tutorial/Gui07b/Gui07b.upp b/tutorial/Gui07b/Gui07b.upp new file mode 100644 index 000000000..7e42bf965 --- /dev/null +++ b/tutorial/Gui07b/Gui07b.upp @@ -0,0 +1,11 @@ +description "Menu - as single lambda\377"; + +uses + CtrlLib; + +file + main.cpp; + +mainconfig + "" = "GUI"; + diff --git a/tutorial/Gui07b/main.cpp b/tutorial/Gui07b/main.cpp new file mode 100644 index 000000000..93c045db2 --- /dev/null +++ b/tutorial/Gui07b/main.cpp @@ -0,0 +1,32 @@ +#include + +using namespace Upp; + +struct MyAppWindow : TopWindow { + MenuBar menu; + + MyAppWindow() { + Title("My application with menu").Sizeable(); + AddFrame(menu); + menu.Set( + [=](Bar& bar) { + bar.Sub("Menu", + [=](Bar& bar) { + bar.Add("Exit", + [=] { + if(PromptOKCancel("Exit MyApp?")) + Break(); + } + ); + } + ); + } + ); + } +}; + +GUI_APP_MAIN +{ + MyAppWindow app; + app.Run(); +} diff --git a/uppsrc/CtrlLib/srcdoc.tpp/Tutorial_en-us.tpp b/uppsrc/CtrlLib/srcdoc.tpp/Tutorial_en-us.tpp index e35f7e38b..0ea82fd97 100644 --- a/uppsrc/CtrlLib/srcdoc.tpp/Tutorial_en-us.tpp +++ b/uppsrc/CtrlLib/srcdoc.tpp/Tutorial_en-us.tpp @@ -265,9 +265,9 @@ KDE.&] [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 for -example [* LeftDown ]and [* MouseMove]. To issue the repainting of -view area, use the [* Refresh] method.&] -[s5; &] +example [* LeftDown, MouseMove] and [* Key]. To issue the repainting +of view area, use the [* Refresh] method.&] +[s5; The following example demonstrates how to handle mouse events:&] [s0;l320;%- [C@(128.0.255)+75 #include][C+75 ][C@(0.0.255)+75 <][C+75 CtrlLib][C@(0.0.255)+75 / ][C+75 CtrlLib][C@(0.0.255)+75 .][C+75 h][C@(0.0.255)+75 >]&] [s0;l320;C+75%- &] @@ -313,8 +313,7 @@ p][C@(0.0.255)+75 .][C+75 y ][C@(0.0.255)+75 `=][C+75 ][C@3+75 0][C+75 ;]&] [s0;l320;C+75%- &] [s0;l320;%- [C+75 GUI`_APP`_MAIN]&] [s0;l320;%- [C+75 `{]&] -[s0;l320;%- [C+75 MyAppWindow app;]&] -[s0;l320;%- [C+75 app][C@(0.0.255)+75 .][C+75 Run();]&] +[s0;l320;%- [C+75 MyAppWindow().Run();]&] [s0;l320;%- [+75 `}]&] [s5; &] [s0;= @@ -322,6 +321,78 @@ p][C@(0.0.255)+75 .][C+75 y ][C@(0.0.255)+75 `=][C+75 ][C@3+75 0][C+75 ;]&] (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) &] [s5; &] +[s5; The following example demonstrates how to handle keyboard events:&] +[s0;l320;%- [C@(128.0.255)+75 #include][C+75 ][C@(0.0.255)+75 <][C+75 CtrlLib][C@(0.0.255)+75 / +][C+75 CtrlLib][C@(0.0.255)+75 .][C+75 h][C@(0.0.255)+75 >]&] +[s0;l320;C+75%- &] +[s0;l320;%- [*C@(0.0.255)+75 using][C+75 ][*C@(0.0.255)+75 namespace][C+75 +Upp;]&] +[s0;l320;C+75%- &] +[s0;l320;%- [*C@(0.0.255)+75 struct][C+75 MyAppWindow ][C@(0.0.255)+75 :][C+75 +TopWindow `{]&] +[s0;l320;%- [C+75 String text ][C@(0.0.255)+75 `=][C+75 ][C@3+75 `"Press +any arrow key...`"][C+75 ;]&] +[s0;l320;C+75%- &] +[s0;l320;%- [C+75 ][*_C@(0.0.255)+75 bool][*_C+75 Key(][*_C@(0.128.128)+75 dword][*_C+75 +key, ][*_C@(0.0.255)+75 int][*_C+75 count) ][*_C@(0.0.255)+75 override][*_C+75 +`{]&] +[s0;l320;%- [C+75 ][*_C@(0.0.255)+75 switch][*_C+75 (key) `{]&] +[s0;l320;%- [C+75 ][*_C@(0.0.255)+75 case][*_C+75 K`_UP][*_C@(0.0.255)+75 :]&] +[s0;l320;%- [C+75 text ][C@(0.0.255)+75 `=][C+75 ][C@3+75 `"Up +⬆`"][C+75 ;]&] +[s0;l320;%- [C+75 ][*_C+75 Refresh();]&] +[s0;l320;%- [C+75 ][*_C@(128.0.255)+75 return][*_C+75 ][*_C@(0.0.255)+75 true][*_C+75 ; +]&] +[s0;l320;%- [C+75 ][*_C@(0.0.255)+75 case][*_C+75 K`_DOWN][*_C@(0.0.255)+75 :]&] +[s0;l320;%- [C+75 text ][C@(0.0.255)+75 `=][C+75 ][C@3+75 `"Down +⬇`"][C+75 ;]&] +[s0;l320;%- [C+75 ][*_C+75 Refresh();]&] +[s0;l320;%- [C+75 ][*_C@(128.0.255)+75 return][*_C+75 ][*_C@(0.0.255)+75 true][*_C+75 ; +]&] +[s0;l320;%- [C+75 ][*_C@(0.0.255)+75 case][*_C+75 K`_LEFT][*_C@(0.0.255)+75 :]&] +[s0;l320;%- [C+75 text ][C@(0.0.255)+75 `=][C+75 ][C@3+75 `"Left +⬅`"][C+75 ;]&] +[s0;l320;%- [C+75 ][*_C+75 Refresh();]&] +[s0;l320;%- [C+75 ][*_C@(128.0.255)+75 return][*_C+75 ][*_C@(0.0.255)+75 true][*_C+75 ; +]&] +[s0;l320;%- [C+75 ][*_C@(0.0.255)+75 case][*_C+75 K`_RIGHT][*_C@(0.0.255)+75 :]&] +[s0;l320;%- [C+75 text ][C@(0.0.255)+75 `=][C+75 ][C@3+75 `"Right +⮕`"][C+75 ;]&] +[s0;l320;%- [C+75 ][*_C+75 Refresh();]&] +[s0;l320;%- [C+75 ][*_C@(128.0.255)+75 return][*_C+75 ][*_C@(0.0.255)+75 true][*_C+75 ; +]&] +[s0;l320;%- [C+75 ][*_C@(0.0.255)+75 default:]&] +[s0;l320;%- [C+75 ][*_C@(128.0.255)+75 return][*_C+75 TopWindow][*_C@(0.0.255)+75 `: +:][*_C+75 Key(key, count);]&] +[s0;l320;%- [C+75 `}]&] +[s0;l320;%- [C+75 `}]&] +[s0;l320;C+75%- &] +[s0;l320;%- [C+75 ][*C@(0.0.255)+75 void][C+75 Paint(Draw][C@(0.0.255)+75 `&][C+75 +w) ][*C@(0.0.255)+75 override][C+75 `{]&] +[s0;l320;%- [C+75 w][C@(0.0.255)+75 .][C+75 DrawRect(GetSize(), +SWhite);]&] +[s0;l320;%- [C+75 w][C@(0.0.255)+75 .][C+75 DrawText(][C@3+75 45][C+75 , +][C@3+75 20][C+75 , text, Arial(][C@3+75 20][C+75 ), Magenta);]&] +[s0;l320;%- [C+75 `}]&] +[s0;l320;C+75%- &] +[s0;l320;%- [C+75 MyAppWindow() `{]&] +[s0;l320;%- [C+75 Title(][C@3+75 `"My application`"][C+75 )][C@(0.0.255)+75 .][C+75 Zoo +mable();]&] +[s0;l320;%- [C+75 SetRect(][C@3+75 0][C+75 , ][C@3+75 0][C+75 , ][C@3+75 400][C+75 , +][C@3+75 100][C+75 );]&] +[s0;l320;%- [C+75 `}]&] +[s0;l320;%- [C+75 `};]&] +[s0;l320;C+75%- &] +[s0;l320;%- [C+75 GUI`_APP`_MAIN]&] +[s0;l320;%- [C+75 `{]&] +[s0;l320;%- [C+75 MyAppWindow()][C@(0.0.255)+75 .][C+75 Run();]&] +[s0;l320;%- [C+75 `}]&] +[s5; &] +[s0;= +@@rawimage:1350&460 +(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) +&] +[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 just From 2e6e3caf1501abcd383e2307293d002d98ed8c3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20R=C4=99bacz?= Date: Fri, 9 Jan 2026 00:31:17 +0100 Subject: [PATCH 7/7] Tutorial: Gui tutorial descriptions. --- tutorial/Gui05a/Gui05a.upp | 2 +- tutorial/Gui05b/Gui05b.upp | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/tutorial/Gui05a/Gui05a.upp b/tutorial/Gui05a/Gui05a.upp index 8fd00f084..45cd358a7 100644 --- a/tutorial/Gui05a/Gui05a.upp +++ b/tutorial/Gui05a/Gui05a.upp @@ -1,4 +1,4 @@ -description "Reacting to input events\377"; +description "Reacting to input events - mouse\377"; uses CtrlLib; diff --git a/tutorial/Gui05b/Gui05b.upp b/tutorial/Gui05b/Gui05b.upp index 5c4f53e15..809d18487 100644 --- a/tutorial/Gui05b/Gui05b.upp +++ b/tutorial/Gui05b/Gui05b.upp @@ -1,3 +1,5 @@ +description "Reacting to input events - keyboard\377"; + uses CtrlLib;