diff --git a/programs/develop/cedit/CEDIT b/programs/develop/cedit/CEDIT index bc0ef97e18..df7899c569 100644 Binary files a/programs/develop/cedit/CEDIT and b/programs/develop/cedit/CEDIT differ diff --git a/programs/develop/cedit/SHORTCUT.TXT b/programs/develop/cedit/SHORTCUT.TXT index 8d8d1ecf0d..22bbc17e14 100644 --- a/programs/develop/cedit/SHORTCUT.TXT +++ b/programs/develop/cedit/SHORTCUT.TXT @@ -7,7 +7,8 @@ ctrl+L преобразовать в нижний регистр ctrl+U преобразовать в верхний регистр ctrl+F показать панель поиска - Esc закрыть панель поиска + Esc закрыть панель поиска; закрыть меню + F10 открыть главное меню F3 найти следующий shift+F3 найти предыдущий ctrl+Z отменить diff --git a/programs/develop/cedit/SRC/CEdit.ob07 b/programs/develop/cedit/SRC/CEdit.ob07 index 90a6788d67..fd8edd5072 100644 --- a/programs/develop/cedit/SRC/CEdit.ob07 +++ b/programs/develop/cedit/SRC/CEdit.ob07 @@ -25,10 +25,10 @@ IMPORT G := Graph, T := Text, E := Encodings, CB := Clipboard, Languages, ChangeLog, Scroll, CheckBox, - RW, Ini, box_lib, Icons, Tabs, Timer; + RW, Ini, EB := EditBox, Icons, Tabs, Timer; CONST - header = "CEdit (08-sep-2021)"; + header = "CEdit (11-sep-2021)"; ShellFilter = ""; EditFilter = "SH|ASM|TXT|INC|OB07|C|CPP|H|PAS|PP|LUA|INI|JSON"; @@ -58,21 +58,11 @@ CONST btnCloseFind = 64; btnHideFind = 65; - btnFile = 70; - btnEdit = 71; - btnMenuSearch = 72; - btnEncoding = 73; - btnEOL = 74; - btnView = 75; - btnSyntax = 76; - btnProgram = 77; - btnTools = 78; - - MainMenuHeight = fontHeight + 7; + mainMenuBtn = 70; btnHeight = 25; btnWidth = 75; - btnTop = MainMenuHeight + 3; + btnTop = Menu.MainMenuHeight + 3; toolBtnSize = 24; toolbarDelim = 7; iconPad = (toolBtnSize - Icons.SIZE) DIV 2; @@ -89,14 +79,14 @@ CONST EDITBOX_MAXCHARS = 500; menuFileX = searchLeft; - menuEditX = menuFileX + 4*fontWidth + 2 + 7; - menuSearchX = menuEditX + 4*fontWidth + 2 + 7; - menuEncodingX = menuSearchX + 6*fontWidth + 2 + 7; - menuEOLX = menuEncodingX + 8*fontWidth + 2 + 7; - menuViewX = menuEOLX + 3*fontWidth + 2 + 7; - menuSyntaxX = menuViewX + 4*fontWidth + 2 + 7; - menuProgramX = menuSyntaxX + 6*fontWidth + 2 + 7; - menuToolsX = menuProgramX + 7*fontWidth + 2 + 7; + menuEditX = menuFileX + 4*fontWidth + 9; + menuSearchX = menuEditX + 4*fontWidth + 9; + menuEncodingX = menuSearchX + 6*fontWidth + 9; + menuEOLX = menuEncodingX + 8*fontWidth + 9; + menuViewX = menuEOLX + 3*fontWidth + 9; + menuSyntaxX = menuViewX + 4*fontWidth + 9; + menuProgramX = menuSyntaxX + 6*fontWidth + 9; + menuToolsX = menuProgramX + 7*fontWidth + 9; menuCut = 1; menuCopy = 2; @@ -176,7 +166,6 @@ CONST menuCR = 142; maxTexts = 32; - scrollDelay = 40; VAR @@ -198,7 +187,7 @@ VAR hScroll, vScroll: Scroll.tScroll; LEFT: INTEGER; - FindEdit, ReplaceEdit, GotoEdit: box_lib.edit_box; + FindEdit, ReplaceEdit, GotoEdit: EB.tEditBox; CS, WH, BKW: CheckBox.tCheckBox; new_searchText, searchText, replaceText, gotoText: T.tString; @@ -212,6 +201,8 @@ VAR menuEOL, menuView, menuSyntax, menuProgram, menuTools, subCurLine, subIndent, subCase, subBookmark: Menu.tMenu; + mainMenu: Menu.tMain; + menuActive: BOOLEAN; icons: INTEGER; @@ -234,7 +225,7 @@ BEGIN END WritePos; -PROCEDURE EditBox_Focus (edit: box_lib.edit_box): BOOLEAN; +PROCEDURE EditBox_Focus (edit: EB.tEditBox): BOOLEAN; VAR res: BOOLEAN; BEGIN @@ -258,7 +249,7 @@ BEGIN END resetTimer; -PROCEDURE EditBox_SetFocus (edit: box_lib.edit_box; value: BOOLEAN); +PROCEDURE EditBox_SetFocus (edit: EB.tEditBox; value: BOOLEAN); BEGIN IF value THEN edit.flags := ORD(BITS(edit.flags) + {1}) @@ -266,12 +257,12 @@ BEGIN edit.flags := ORD(BITS(edit.flags) - {1}) END; IF search & searchOpened THEN - box_lib.edit_box_draw(edit) + EB.paint(edit) END END EditBox_SetFocus; -PROCEDURE SetFocus (edit: box_lib.edit_box; value: BOOLEAN); +PROCEDURE SetFocus (edit: EB.tEditBox; value: BOOLEAN); BEGIN EditBox_SetFocus(FindEdit, FALSE); EditBox_SetFocus(ReplaceEdit, FALSE); @@ -558,9 +549,9 @@ BEGIN FindEdit.left := left; ReplaceEdit.left := left; GotoEdit.left := left; - box_lib.edit_box_draw(FindEdit); - box_lib.edit_box_draw(ReplaceEdit); - box_lib.edit_box_draw(GotoEdit); + EB.paint(FindEdit); + EB.paint(ReplaceEdit); + EB.paint(GotoEdit); y := top + 200; K.CreateButton(btnFindNext, left, y, btnWidth, btnHeight, K.btnColor, "next"); INC(y, btnHeight + 10); K.CreateButton(btnReplace, left, y, btnWidth, btnHeight, K.btnColor, "replace"); INC(y, btnHeight + 10); @@ -583,24 +574,6 @@ VAR END drawToolbarBtn; - PROCEDURE drawMainMenu (menu: Menu.tMenu; x: INTEGER; btn: INTEGER; caption: ARRAY OF WCHAR); - VAR - menuColor, textColor, n: INTEGER; - BEGIN - IF menu.tid # 0 THEN - menuColor := K.textColor; - textColor := K.winColor - ELSE - menuColor := K.winColor; - textColor := K.textColor - END; - n := LENGTH(caption); - K.DrawRect(x, 0, n*fontWidth + 2, MainMenuHeight, menuColor); - K.CreateButton(btn + ORD({30}), x, 0, n*fontWidth + 2, MainMenuHeight, K.btnColor, ""); - K.DrawText(x + 1, (MainMenuHeight - fontHeight) DIV 2 + 1, textColor, caption) - END drawMainMenu; - - BEGIN K.BeginDraw; K.CreateWindow(30 + K.GetTickCount() MOD 128, 30 + K.GetTickCount() MOD 128, winWidth, winHeight, K.winColor, 73H, 0, 0, header); @@ -614,16 +587,7 @@ BEGIN K.DrawRect(0, 0, width, TOP, K.winColor); K.DrawRect(0, 0, LEFT, height, K.winColor); K.DrawRect(LEFT + canvas.width + 1, TOP + canvas.height, scrollWidth - 1, scrollWidth, K.winColor); - - drawMainMenu(menuFile, menuFileX, btnFile, "file"); - drawMainMenu(menuEdit, menuEditX, btnEdit, "edit"); - drawMainMenu(menuSearch, menuSearchX, btnMenuSearch, "search"); - drawMainMenu(menuEncoding, menuEncodingX, btnEncoding, "encoding"); - drawMainMenu(menuEOL, menuEOLX, btnEOL, "eol"); - drawMainMenu(menuView, menuViewX, btnView, "view"); - drawMainMenu(menuSyntax, menuSyntaxX, btnSyntax, "syntax"); - drawMainMenu(menuProgram, menuProgramX, btnProgram, "program"); - drawMainMenu(menuTools, menuToolsX, btnTools, "tools"); + Menu.DrawMain(mainMenu); x := searchLeft; @@ -687,16 +651,6 @@ BEGIN END mouse; -PROCEDURE getKBState (VAR shift, ctrl: BOOLEAN); -VAR - kbState: SET; -BEGIN - kbState := K.GetControlKeys(); - shift := {0, 1} * kbState # {}; - ctrl := {2, 3} * kbState # {}; -END getKBState; - - PROCEDURE stopTimer; BEGIN T.hideCursor; @@ -973,14 +927,14 @@ BEGIN END open; -PROCEDURE createEdit (left, top: INTEGER): box_lib.edit_box; +PROCEDURE createEdit (left, top: INTEGER): EB.tEditBox; VAR - edit, EditBox0: box_lib.edit_box; + edit, EditBox0: EB.tEditBox; BEGIN NEW(EditBox0); EditBox0.text := K.malloc(EDITBOX_MAXCHARS + 2); ASSERT(EditBox0.text # 0); - edit := box_lib.kolibri_new_edit_box(left, top, EditBox_Width, EDITBOX_MAXCHARS, EditBox0); + edit := EB.create(left, top, EditBox_Width, EDITBOX_MAXCHARS, EditBox0); edit.flags := 4002H; edit.text_color := 30000000H; EditBox_SetFocus(edit, FALSE) @@ -994,18 +948,18 @@ BEGIN ReplaceEdit := createEdit(searchLeft, TOP + 20 + 55); GotoEdit := createEdit(searchLeft, TOP + 20 + 330); GotoEdit.flags := ORD(BITS(GotoEdit.flags) + BITS(8000H)); - BKW := CheckBox.create("backward"); - CS := CheckBox.create("match case"); - WH := CheckBox.create("whole word"); + CheckBox.create("backward", BKW); + CheckBox.create("match case", CS); + CheckBox.create("whole word", WH); END createSearchForm; -PROCEDURE EditBox_GetValue (edit: box_lib.edit_box; VAR s: ARRAY OF WCHAR); +PROCEDURE EditBox_GetValue (edit: EB.tEditBox; VAR s: ARRAY OF WCHAR); VAR str: ARRAY EDITBOX_MAXCHARS + 1 OF CHAR; i: INTEGER; BEGIN - box_lib.edit_box_get_value(edit, str); + EB.getValue(edit, str); i := 0; WHILE str[i] # 0X DO s[i] := WCHR(E.cp866[ORD(str[i])]); @@ -1037,19 +991,11 @@ VAR scrollX, scrollY: INTEGER; shift, ctrl: BOOLEAN; BEGIN - getKBState(shift, ctrl); - IF ~hScroll.mouse THEN - Scroll.MouseDown(hScroll, x + LEFT, y + TOP); - T.getScroll(text, scrollX, scrollY); - T.scroll(text, hScroll.value - scrollX, 0); - repaint - END; - IF ~vScroll.mouse THEN - Scroll.MouseDown(vScroll, x + LEFT, y + TOP); - T.getScroll(text, scrollX, scrollY); - T.scroll(text, 0, vScroll.value - scrollY); - repaint - END; + K.getKBState(shift, ctrl); + Scroll.MouseDown(hScroll, x + LEFT, y + TOP); + Scroll.MouseDown(vScroll, x + LEFT, y + TOP); + T.getScroll(text, scrollX, scrollY); + T.scroll(text, hScroll.value - scrollX, vScroll.value - scrollY); IF search & searchOpened THEN CheckBox.MouseDown(BKW, x + LEFT, y + TOP); CheckBox.MouseDown(CS, x + LEFT, y + TOP); @@ -1061,9 +1007,9 @@ BEGIN IF ~shift THEN T.resetSelect(text) END; - T.mouse(text, x, y); - repaint - END + T.mouse(text, x, y) + END; + repaint RETURN K.GetTickCount() END click; @@ -1112,7 +1058,7 @@ BEGIN Menu.close(subIndent); Menu.close(subCase); Menu.close(subBookmark); - Menu.close(context); + Menu.close(context) END CloseMenu; @@ -1178,9 +1124,8 @@ BEGIN K.WinPos(winX, winY); K.ClientPos(cliX, cliY); x := winX + cliX; - y := MainMenuHeight + winY + cliY + y := Menu.MainMenuHeight + winY + cliY END; - selected := T.selected(text); IF menu = menuFile THEN @@ -1273,6 +1218,7 @@ END ShowMenu; PROCEDURE receiveIPC; VAR scrollIPC: BOOLEAN; + item: List.tItem; BEGIN scrollIPC := FALSE; IF IPC[0] = Timer.ID THEN @@ -1284,17 +1230,8 @@ BEGIN ELSIF IPC[0] = mainTID THEN IF IPC[2] = Scroll.ScrollIPC THEN Scroll.change(hScroll); - IF hScroll.Dec THEN - T.scroll(text, -1, 0) - ELSIF hScroll.Inc THEN - T.scroll(text, 1, 0) - END; Scroll.change(vScroll); - IF vScroll.Dec THEN - T.scroll(text, 0, -1) - ELSIF vScroll.Inc THEN - T.scroll(text, 0, 1) - END; + T.scroll(text, ORD(hScroll.Inc) - ORD(hScroll.Dec), ORD(vScroll.Inc) - ORD(vScroll.Dec)); IF menuActive THEN draw_window; @@ -1303,7 +1240,7 @@ BEGIN repaint END; - IF (0 IN K.MouseState()) THEN + IF 0 IN K.MouseState() THEN WHILE (0 IN K.MouseState()) & (delay > 0) DO K.Pause(1); DEC(delay) @@ -1315,15 +1252,25 @@ BEGIN Scroll.SendIPC; delay := 2 ELSE - delay := scrollDelay + delay := Scroll.Delay END ELSE - delay := scrollDelay + delay := Scroll.Delay END END; IPC[2] := 0 - ELSIF ~Menu.isSender(IPC[0]) THEN - IPC[2] := 0 + ELSE + IF ~Menu.isSender(IPC[0]) THEN + IPC[2] := 0 + ELSE + IF IPC[2] < 0 THEN + item := List.getItem(mainMenu, (-IPC[2] - mainMenuBtn) MOD mainMenu.count); + IF item # NIL THEN + ShowMenu(item(Menu.tMainItem).menu) + END; + IPC[2] := 0 + END + END END; CASE IPC[2] OF |0: @@ -1465,12 +1412,13 @@ VAR shift, ctrl: BOOLEAN; BEGIN menuItem := -1; - getKBState(shift, ctrl); + K.getKBState(shift, ctrl); IF ctrl THEN CASE key DIV 65536 OF |17: menuItem := menuClose |21: menuItem := menuRedo |30: menuItem := menuSelectAll + |32: menuItem := menuDuplicate |33: menuItem := menuFind |34: menuItem := menuGoto |44: menuItem := menuUndo @@ -1481,6 +1429,12 @@ BEGIN |31: menuItem := menuSave |49: menuItem := menuNew |67: menuItem := menuBuild + |83: menuItem := menuRemove + |22: menuItem := menuUpper + |38: menuItem := menuLower + |60: menuItem := menuToggleBookmark + |72: menuItem := menuMoveUp + |80: menuItem := menuMoveDown ELSE END ELSE @@ -1488,6 +1442,16 @@ BEGIN menuItem := menuDelete ELSIF key DIV 65536 = 67 THEN menuItem := menuRun + ELSIF key DIV 65536 = 15 THEN + menuItem := menuIncInd + ELSIF (key DIV 65536 = 14) & shift THEN + menuItem := menuDecInd + ELSIF key DIV 65536 = 60 THEN + IF shift THEN + menuItem := menuPrevBookmark + ELSE + menuItem := menuNextBookmark + END END END; IF menuItem # -1 THEN @@ -1726,8 +1690,8 @@ VAR keyCode: INTEGER; shift, ctrl: BOOLEAN; BEGIN + K.getKBState(shift, ctrl); keyCode := key DIV 65536; - getKBState(shift, ctrl); IF confirm THEN IF keyCode = 28 THEN (* Enter *) save(text); @@ -1760,6 +1724,9 @@ BEGIN ELSE Script(runScript) END + ELSIF keyCode = 68 THEN (* F10 *) + key := -1; + ShowMenu(menuFile) ELSIF keyCode = 1 THEN (* Esc *) key := -1; IF search THEN @@ -1783,20 +1750,20 @@ BEGIN SetFocus(GotoEdit, TRUE) ELSE IF EditBox_Focus(FindEdit) THEN - box_lib.edit_box_key(FindEdit, key); + EB.key(FindEdit, key); EditBox_GetValue(FindEdit, new_searchText); IF new_searchText # searchText THEN searchText := new_searchText; notFound := ~T.search(text, searchText, cs, whole) END ELSIF EditBox_Focus(ReplaceEdit) THEN - box_lib.edit_box_key(ReplaceEdit, key); + EB.key(ReplaceEdit, key); EditBox_GetValue(ReplaceEdit, replaceText) ELSIF EditBox_Focus(GotoEdit) THEN IF (key DIV 256) MOD 256 = 13 THEN goto ELSE - box_lib.edit_box_key(GotoEdit, key) + EB.key(GotoEdit, key) END ELSE CASE keyCode OF @@ -1858,9 +1825,10 @@ PROCEDURE BtnClick; VAR btn: INTEGER; middle, exit: BOOLEAN; + menu: Menu.tMenu; BEGIN btn := K.ButtonCode(middle); - IF (Tabs.btnID <= btn) & (btn <= Tabs.btnID + maxTexts - 1) THEN + IF U.between(Tabs.btnID, btn, Tabs.btnID + maxTexts - 1) THEN DEC(btn, Tabs.btnID); IF middle THEN IF texts[btn].modified THEN @@ -1876,30 +1844,19 @@ BEGIN btn := 0 END END; + IF btn # 0 THEN + menu := Menu.ClickMain(mainMenu, btn); + IF menu # NIL THEN + ShowMenu(menu); + btn := 0 + END + END; CASE btn OF |Tabs.btnID - 1: Tabs.scroll(tabs, -1); switch := TRUE; repaint |Tabs.btnID - 2: Tabs.scroll(tabs, +1); switch := TRUE; repaint |0: - |btnFile: - ShowMenu(menuFile) - |btnEdit: - ShowMenu(menuEdit) - |btnMenuSearch: - ShowMenu(menuSearch) - |btnEncoding: - ShowMenu(menuEncoding) - |btnEOL: - ShowMenu(menuEOL) - |btnView: - ShowMenu(menuView) - |btnSyntax: - ShowMenu(menuSyntax) - |btnProgram: - ShowMenu(menuProgram) - |btnTools: - ShowMenu(menuTools) |btnNo: exit := closing; closeFile(FALSE, curText); @@ -1982,12 +1939,12 @@ VAR scroll, x, y, scrollX, scrollY: INTEGER; - PROCEDURE EditBox (eb: box_lib.edit_box); + PROCEDURE EditBox (eb: EB.tEditBox); VAR focus: BOOLEAN; BEGIN focus := EditBox_Focus(eb); - box_lib.edit_box_mouse(eb); + EB.mouse(eb); IF focus # EditBox_Focus(eb) THEN SetFocus(eb, TRUE); repaint @@ -2037,12 +1994,8 @@ BEGIN END; IF 24 IN msState THEN mouse(x, y); - IF ~hScroll.mouse THEN - Scroll.MouseDown(hScroll, x + LEFT, y + TOP) - END; - IF ~vScroll.mouse THEN - Scroll.MouseDown(vScroll, x + LEFT, y + TOP) - END; + Scroll.MouseDown(hScroll, x + LEFT, y + TOP); + Scroll.MouseDown(vScroll, x + LEFT, y + TOP); IF search & searchOpened THEN CheckBox.MouseDown(BKW, x + LEFT, y + TOP); CheckBox.MouseDown(CS, x + LEFT, y + TOP); @@ -2111,7 +2064,7 @@ VAR resized: BOOLEAN; firstClickX, firstClickY, time: INTEGER; BEGIN - delay := scrollDelay; + delay := Scroll.Delay; K.GetSystemColors; Icons.get(icons, grayIcons); modified := FALSE; @@ -2163,6 +2116,17 @@ BEGIN menuProgram := CreateMenuProgram(); menuTools := CreateMenuTools(); + mainMenu := Menu.CreateMain(mainMenuBtn); + Menu.AddMainItem(mainMenu, "file", menuFile); + Menu.AddMainItem(mainMenu, "edit", menuEdit); + Menu.AddMainItem(mainMenu, "search", menuSearch); + Menu.AddMainItem(mainMenu, "encoding", menuEncoding); + Menu.AddMainItem(mainMenu, "eol", menuEOL); + Menu.AddMainItem(mainMenu, "view", menuView); + Menu.AddMainItem(mainMenu, "syntax", menuSyntax); + Menu.AddMainItem(mainMenu, "program", menuProgram); + Menu.AddMainItem(mainMenu, "tools", menuTools); + Ini.getSettings(buildScript, runScript, debugScript); IF fileName = "" THEN text := T.New(); @@ -2200,13 +2164,13 @@ BEGIN Timer.create(mainTID); WHILE TRUE DO CASE K.WaitForEvent() OF - |1: IF Menu.redraw THEN - Redraw(resized, width, height, cliWidth, cliHeight) - ELSE + |1: (*IF Menu.redraw THEN*) + Redraw(resized, width, height, cliWidth, cliHeight) + (*ELSE Menu.Redraw; K.CreateWindow(30 + K.GetTickCount() MOD 128, 30 + K.GetTickCount() MOD 128, winWidth, winHeight, K.winColor, 73H, 0, 0, header); repaint - END + END*) |2: KeyDown(K.GetKey()) |3: BtnClick |6: MouseEvent(resized, firstClickX, firstClickY, time) diff --git a/programs/develop/cedit/SRC/CheckBox.ob07 b/programs/develop/cedit/SRC/CheckBox.ob07 index 2c2f130c1a..268e52dfda 100644 --- a/programs/develop/cedit/SRC/CheckBox.ob07 +++ b/programs/develop/cedit/SRC/CheckBox.ob07 @@ -19,88 +19,78 @@ MODULE CheckBox; -IMPORT G := Graph, K := KolibriOS; +IMPORT G := Graph, K := KolibriOS, U := Utils; + CONST padding = 4; + fontWidth = K.fontWidth; + fontHeight = K.fontHeight; + TYPE - tCheckBox* = POINTER TO RECORD + tCheckBox* = RECORD left*, top*: INTEGER; width, height: INTEGER; - value*, mouse*: BOOLEAN; + value*, mouse: BOOLEAN; text: ARRAY 32 OF WCHAR; canvas: G.tCanvas END; -PROCEDURE mark (canvas: G.tCanvas); -BEGIN - G.DLine(canvas, 2, 6, 6, -1); - G.DLine(canvas, 2, 6, 7, -1); - G.DLine(canvas, 7, 13, 9, 1); - G.DLine(canvas, 7, 13, 10, 1); -END mark; - - PROCEDURE paint* (chkbox: tCheckBox); VAR canvas: G.tCanvas; - fontHeight: INTEGER; BEGIN canvas := chkbox.canvas; - fontHeight := canvas.font.height - 1; - G.SetColor(canvas, K.winColor); - G.clear(canvas); - G.SetColor(canvas, 0FFFFFFH); - G.FillRect(canvas, 0, 0, fontHeight, fontHeight); - G.SetColor(canvas, K.borderColor); - G.Rect(canvas, 0, 0, fontHeight, fontHeight); - IF chkbox.value THEN - G.SetColor(canvas, 0008000H); - mark(canvas) - END; - G.SetTextColor(canvas, K.textColor); - G.SetBkColor(canvas, K.winColor); - G.TextOut2(canvas, canvas.font.height + padding, 0, chkbox.text, LENGTH(chkbox.text)); - G.DrawCanvas(canvas, chkbox.left, chkbox.top) + IF canvas # NIL THEN + G.SetColor(canvas, K.winColor); + G.clear(canvas); + G.SetColor(canvas, 0FFFFFFH); + G.FillRect(canvas, 0, 0, fontHeight - 1, fontHeight - 1); + G.SetColor(canvas, K.borderColor); + G.Rect(canvas, 0, 0, fontHeight - 1, fontHeight - 1); + IF chkbox.value THEN + G.SetColor(canvas, 0008000H); + G.DLine(canvas, 2, 6, 6, -1); + G.DLine(canvas, 2, 6, 7, -1); + G.DLine(canvas, 7, 13, 9, 1); + G.DLine(canvas, 7, 13, 10, 1) + END; + G.SetTextColor(canvas, K.textColor); + G.SetBkColor(canvas, K.winColor); + G.TextOut2(canvas, fontHeight + padding, 0, chkbox.text, LENGTH(chkbox.text)); + G.DrawCanvas(canvas, chkbox.left, chkbox.top) + END END paint; -PROCEDURE create* (text: ARRAY OF WCHAR): tCheckBox; +PROCEDURE create* (text: ARRAY OF WCHAR; VAR chkbox: tCheckBox); VAR res: tCheckBox; - font: G.tFont; BEGIN - font := G.CreateFont(1, "", {}); - NEW(res); res.left := 0; res.top := 0; res.value := FALSE; res.mouse := FALSE; COPY(text, res.text); - res.canvas := G.CreateCanvas(font.height + padding + LENGTH(res.text)*font.width, font.height + 1); - G.SetFont(res.canvas, font); + res.canvas := G.CreateCanvas(fontHeight + padding + LENGTH(res.text)*fontWidth, fontHeight + 1); + G.SetFont(res.canvas, G.CreateFont(1, "", {})); res.width := res.canvas.width; res.height := res.canvas.height; - RETURN res + chkbox := res END create; -PROCEDURE between (a, b, c: INTEGER): BOOLEAN; - RETURN (a <= b) & (b <= c) -END between; - - -PROCEDURE MouseDown* (chkbox: tCheckBox; x, y: INTEGER); +PROCEDURE MouseDown* (VAR chkbox: tCheckBox; x, y: INTEGER); BEGIN - IF (chkbox # NIL) & ~chkbox.mouse THEN + IF (chkbox.canvas # NIL) & ~chkbox.mouse THEN DEC(x, chkbox.left); DEC(y, chkbox.top); chkbox.mouse := TRUE; - IF between(0, x, chkbox.width) & between(0, y, chkbox.height) THEN + IF U.between(0, x, chkbox.width) & U.between(0, y, chkbox.height) THEN chkbox.value := ~chkbox.value; END; paint(chkbox) @@ -108,9 +98,9 @@ BEGIN END MouseDown; -PROCEDURE MouseUp* (chkbox: tCheckBox); +PROCEDURE MouseUp* (VAR chkbox: tCheckBox); BEGIN - IF chkbox # NIL THEN + IF chkbox.canvas # NIL THEN chkbox.mouse := FALSE END END MouseUp; diff --git a/programs/develop/cedit/SRC/EditBox.ob07 b/programs/develop/cedit/SRC/EditBox.ob07 new file mode 100644 index 0000000000..1d639d25ce --- /dev/null +++ b/programs/develop/cedit/SRC/EditBox.ob07 @@ -0,0 +1,144 @@ +(* + Copyright 2016, 2017, 2020, 2021 Anton Krotov + + This file is part of CEdit. + + CEdit is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + CEdit is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with CEdit. If not, see . +*) + +MODULE EditBox; + +IMPORT sys := SYSTEM, KOSAPI; + + +TYPE + + tEditBox* = POINTER TO RECORD + width*, + left*, + top*, + color*, + shift_color, + focus_border_color, + blur_border_color, + text_color*, + max: INTEGER; + text*: INTEGER; + mouse_variable: tEditBox; + flags*, + + size, + pos: INTEGER; + (* The following struct members are not used by the users of API *) + offset, cl_curs_x, cl_curs_y, shift, shift_old, height, char_width: INTEGER + END; + + EditBoxKey = PROCEDURE (eb: tEditBox); + + +VAR + + key_proc: EditBoxKey; + paint *: PROCEDURE (eb: tEditBox); + mouse *: PROCEDURE (eb: tEditBox); + setValue *: PROCEDURE (eb: tEditBox; text: INTEGER); + + +PROCEDURE _key (key: INTEGER; key_proc: EditBoxKey; text: tEditBox); +BEGIN + sys.CODE( + 08BH, 045H, 008H, (* mov eax, dword [ebp + 8] *) + 08BH, 055H, 00CH, (* mov edx, dword [ebp + 12] *) + 08BH, 04DH, 010H, (* mov ecx, dword [ebp + 16] *) + 051H, (* push ecx *) + 0FFH, 0D2H (* call edx *) + ) +END _key; + + +PROCEDURE key* (text: tEditBox; key: INTEGER); +BEGIN + _key(key, key_proc, text) +END key; + + +PROCEDURE getValue* (text: tEditBox; VAR str: ARRAY OF CHAR); +VAR + ptr, max, i: INTEGER; + +BEGIN + ptr := text.text; + max := text.max; + ASSERT(max < LEN(str)); + i := 0; + REPEAT + sys.GET(ptr, str[i]); + INC(i); + INC(ptr) + UNTIL (str[i - 1] = 0X) OR (i = max); + str[i] := 0X +END getValue; + + +PROCEDURE create* (tlx, tly, width, max_chars: INTEGER; editbox_interlock: tEditBox): tEditBox; +VAR + new_textbox: tEditBox; + +BEGIN + NEW(new_textbox); + + new_textbox.width := width; + new_textbox.left := tlx; + new_textbox.top := tly; + new_textbox.color := 0FFFFFFH; + new_textbox.shift_color := 06A9480H; + new_textbox.focus_border_color := 0; + new_textbox.blur_border_color := 06A9480H; + new_textbox.text_color := 0; + new_textbox.max := max_chars; + new_textbox.text := KOSAPI.malloc(max_chars + 2); + ASSERT(new_textbox.text # 0); + new_textbox.mouse_variable := editbox_interlock; + new_textbox.flags := 0 + + RETURN new_textbox +END create; + + +PROCEDURE GetProc (Lib, v: INTEGER; name: ARRAY OF CHAR); +VAR + a: INTEGER; +BEGIN + a := KOSAPI.GetProcAdr(name, Lib); + ASSERT(a # 0); + sys.PUT(v, a) +END GetProc; + + +PROCEDURE main; +VAR + Lib: INTEGER; +BEGIN + Lib := KOSAPI.LoadLib("/rd/1/lib/box_lib.obj"); + ASSERT(Lib # 0); + GetProc(Lib, sys.ADR(paint), "edit_box"); + GetProc(Lib, sys.ADR(key_proc), "edit_box_key"); + GetProc(Lib, sys.ADR(mouse), "edit_box_mouse"); + GetProc(Lib, sys.ADR(setValue), "edit_box_set_text"); +END main; + + +BEGIN + main +END EditBox. \ No newline at end of file diff --git a/programs/develop/cedit/SRC/KolibriOS.ob07 b/programs/develop/cedit/SRC/KolibriOS.ob07 index cbb6f010c8..84d9da97e7 100644 --- a/programs/develop/cedit/SRC/KolibriOS.ob07 +++ b/programs/develop/cedit/SRC/KolibriOS.ob07 @@ -359,4 +359,14 @@ BEGIN END GetSystemColors; +PROCEDURE getKBState* (VAR shift, ctrl: BOOLEAN); +VAR + kbState: SET; +BEGIN + kbState := GetControlKeys(); + shift := {0, 1} * kbState # {}; + ctrl := {2, 3} * kbState # {}; +END getKBState; + + END KolibriOS. \ No newline at end of file diff --git a/programs/develop/cedit/SRC/Menu.ob07 b/programs/develop/cedit/SRC/Menu.ob07 index 685a9c48af..4de43f73cf 100644 --- a/programs/develop/cedit/SRC/Menu.ob07 +++ b/programs/develop/cedit/SRC/Menu.ob07 @@ -20,12 +20,14 @@ MODULE Menu; IMPORT - SYSTEM, G := Graph, List, K := KolibriOS; + SYSTEM, G := Graph, List, K := KolibriOS, U := Utils, KOSAPI; CONST fontHeight = 22; fontWidth = 8; + MainMenuHeight* = K.fontHeight + 7; + RIGHT = 16; LEFT = 16; TOP = 1; @@ -44,10 +46,17 @@ CONST TYPE + tMainItem* = POINTER TO descMainItem; + + tMain* = POINTER TO RECORD (List.tList) + id: INTEGER + END; + tMenu* = POINTER TO RECORD tid*: INTEGER; - active*: BOOLEAN; + active*, keyboard: BOOLEAN; parent*, child: tMenu; + mainID: INTEGER; winX, winY, width*, height*: INTEGER; selItem, cliItem: INTEGER; @@ -66,6 +75,13 @@ TYPE child: tMenu END; + descMainItem = RECORD (List.tItem) + id*, x: INTEGER; + text: ARRAY 32 OF WCHAR; + menu*: tMenu; + main: tMain + END; + tClick = PROCEDURE (menu: tMenu; id: INTEGER); tKey = PROCEDURE (menu: tMenu; key: INTEGER): BOOLEAN; tProc = PROCEDURE; @@ -75,12 +91,98 @@ VAR TIDs: ARRAY maxLEVEL + 1 OF INTEGER; resetTimer: tProc; _open: PROCEDURE (m: tMenu; x, y: INTEGER); - redraw*: BOOLEAN; + (*redraw*: BOOLEAN;*) (* backColor, foreColor, selBackColor, selForeColor, disBackColor, disForeColor, disSelBackColor, disSelForeColor: INTEGER; *) +PROCEDURE AddMainItem* (main: tMain; text: ARRAY OF WCHAR; menu: tMenu); +VAR + item, prev: tMainItem; +BEGIN + NEW(item); + item.id := main.id + main.count; + COPY(text, item.text); + item.menu := menu; + item.main := main; + menu.mainID := item.id; + List.append(main, item); + prev := item.prev(tMainItem); + IF prev # NIL THEN + item.x := prev.x + LENGTH(prev.text)*fontWidth + 9 + ELSE + item.x := 0 + END +END AddMainItem; + + +PROCEDURE CreateMain* (id: INTEGER): tMain; +VAR + res: tMain; + list: List.tList; +BEGIN + NEW(res); + res.id := id; + list := List.create(res) + RETURN res +END CreateMain; + + +PROCEDURE drawMainItem (item: tMainItem); +VAR + menuColor, textColor, n: INTEGER; +BEGIN + IF item.menu.tid # 0 THEN + menuColor := K.textColor; + textColor := K.winColor + ELSE + menuColor := K.winColor; + textColor := K.textColor + END; + n := LENGTH(item.text); + K.DrawRect(item.x, 0, n*fontWidth + 2, MainMenuHeight, menuColor); + K.CreateButton(item.id + ORD({30}), item.x, 0, n*fontWidth + 2, MainMenuHeight, K.btnColor, ""); + K.DrawText(item.x + 1, (MainMenuHeight - K.fontHeight) DIV 2 + 1, textColor, item.text) +END drawMainItem; + + +PROCEDURE DrawMain* (main: tMain); +VAR + item: List.tItem; +BEGIN + item := main.first; + WHILE item # NIL DO + drawMainItem(item(tMainItem)); + item := item.next + END +END DrawMain; + + +PROCEDURE getMainID (m: tMenu): INTEGER; +BEGIN + WHILE m.parent # NIL DO + m := m.parent + END + RETURN m.mainID +END getMainID; + + +PROCEDURE ClickMain* (main: tMain; btn: INTEGER): tMenu; +VAR + item: List.tItem; + res: tMenu; +BEGIN + item := List.getItem(main, btn - main.id); + IF item # NIL THEN + res := item(tMainItem).menu + ELSE + res := NIL + END + RETURN res +END ClickMain; + + PROCEDURE isSender* (tid: INTEGER): BOOLEAN; VAR i: INTEGER; @@ -95,13 +197,24 @@ END isSender; PROCEDURE exit (m: tMenu); BEGIN - m.tid := 0; m.active := FALSE; - resetTimer; + resetTimer; + m.tid := 0; K.Exit END exit; +PROCEDURE escape (m: tMenu); +BEGIN + m.active := FALSE; + IF m.parent = NIL THEN + resetTimer + END; + m.tid := 0; + K.Exit +END escape; + + PROCEDURE repaint (m: tMenu); VAR y, i, X, Y1, Y2: INTEGER; @@ -202,14 +315,17 @@ END mouse; PROCEDURE close* (m: tMenu); +VAR + temp: INTEGER; BEGIN IF (m # NIL) & (m.tid # 0) THEN IF m.child # NIL THEN close(m.child); m.child := NIL END; - K.ExitID(m.tid); - m.tid := 0; + temp := m.tid; + m.tid := 0; + K.ExitID(temp); m.active := FALSE END END close; @@ -219,19 +335,28 @@ PROCEDURE click (m: tMenu; i: INTEGER); VAR item: List.tItem; p: tMenu; + id: INTEGER; BEGIN - item := List.getItem(m.items, i); - IF (item # NIL) & item(tItem).enabled & (item(tItem).child = NIL) THEN - m.click(m, item(tItem).id); - p := m.parent; - WHILE p # NIL DO - p.child := NIL; - close(p); - p := p.parent - END; - redraw := TRUE; - exit(m) - END + id := -1; + IF i < 0 THEN + id := i + ELSE + item := List.getItem(m.items, i); + IF (item # NIL) & item(tItem).enabled & (item(tItem).child = NIL) THEN + id := item(tItem).id + END + END; + IF id # -1 THEN + m.click(m, id); + p := m.parent; + WHILE p # NIL DO + p.child := NIL; + close(p); + p := p.parent + END; + (*redraw := TRUE;*) + exit(m) + END END click; @@ -248,68 +373,100 @@ END isActive; PROCEDURE closeChild (m: tMenu); BEGIN IF m.child # NIL THEN - redraw := FALSE; + (*redraw := FALSE;*) close(m.child); m.child := NIL END END closeChild; -PROCEDURE submenu (m: tMenu); +PROCEDURE submenu (m: tMenu; keyboard: BOOLEAN): BOOLEAN; VAR item: List.tItem; + res: BOOLEAN; BEGIN + res := FALSE; item := List.getItem(m.items, m.selItem); IF (item # NIL) & item(tItem).enabled & (item(tItem).child # NIL) THEN + res := TRUE; IF ~opened(item(tItem).child) THEN closeChild(m); + item(tItem).child.keyboard := keyboard; _open(item(tItem).child, m.winX + m.width - 2, m.winY + m.selItem*fontHeight); - m.child := item(tItem).child + m.child := item(tItem).child; END ELSE closeChild(m) END + RETURN res END submenu; PROCEDURE [stdcall] window (m: tMenu); VAR x, y: INTEGER; - key: INTEGER; + key, temp: INTEGER; msState: SET; + shift, ctrl: BOOLEAN; BEGIN - m.selItem := -1; + m.selItem := ORD(m.keyboard) - 1; m.cliItem := -1; + m.keyboard := FALSE; K.SetEventsMask({0, 1, 5}); WHILE TRUE DO CASE K.WaitForEvent() OF |1: draw_window(m) |2: + K.getKBState(shift, ctrl); key := K.GetKey(); - IF key DIV 65536 = 72 THEN - DEC(m.selItem); - IF m.selItem < 0 THEN - m.selItem := 0 - END - ELSIF key DIV 65536 = 80 THEN - INC(m.selItem); - IF m.selItem >= m.items.count THEN - m.selItem := m.items.count - 1 - END - ELSIF key DIV 65536 = 28 THEN - IF m.selItem >= 0 THEN - click(m, m.selItem) - END; - m.cliItem := -1 - ELSIF key DIV 65536 = 77 THEN - submenu(m) - ELSIF key DIV 65536 = 75 THEN - IF m.parent # NIL THEN - exit(m) + IF ~shift & ~ ctrl THEN + IF key DIV 65536 = 72 THEN + DEC(m.selItem); + IF m.selItem < 0 THEN + m.selItem := m.items.count - 1 + END + ELSIF key DIV 65536 = 80 THEN + INC(m.selItem); + IF m.selItem >= m.items.count THEN + m.selItem := 0 + END + ELSIF key DIV 65536 = 28 THEN + IF m.selItem >= 0 THEN + click(m, m.selItem) + END; + m.cliItem := -1 + ELSIF key DIV 65536 = 77 THEN + IF ~submenu(m, TRUE) THEN + click(m, -(getMainID(m) + 1)) + END; + m.cliItem := -1 + ELSIF key DIV 65536 = 75 THEN + IF m.parent # NIL THEN + escape(m) + ELSE + click(m, -(getMainID(m) - 1)) + END; + m.cliItem := -1 + ELSIF key DIV 65536 = 1 THEN + escape(m) + ELSE + IF m.key(m, key) THEN + IF m.parent # NIL THEN + temp := m.parent.tid; + m.parent.tid := 0; + K.ExitID(temp) + END; + exit(m) + END END ELSE IF m.key(m, key) THEN + IF m.parent # NIL THEN + temp := m.parent.tid; + m.parent.tid := 0; + K.ExitID(temp) + END; exit(m) END END; @@ -337,7 +494,7 @@ BEGIN END END; repaint(m); - submenu(m) + IF submenu(m, FALSE) THEN END END END END window; @@ -361,12 +518,14 @@ VAR L: INTEGER; BEGIN IF m.tid = 0 THEN - m.winX := x; - m.winY := y; L := level(m); - SYSTEM.PUT(SYSTEM.ADR(stack[L][LEN(stack[0]) - 1]), m); - m.tid := K.CreateThread(SYSTEM.ADR(window), stack[L]); - TIDs[L] := m.tid + IF KOSAPI.sysfunc3(18, 21, TIDs[L]) = 0 THEN + m.winX := x; + m.winY := y; + SYSTEM.PUT(SYSTEM.ADR(stack[L][LEN(stack[0]) - 1]), m); + m.tid := K.CreateThread(SYSTEM.ADR(window), stack[L]); + TIDs[L] := m.tid + END END END open; @@ -462,6 +621,7 @@ BEGIN m.active := FALSE; m.parent := NIL; m.child := NIL; + m.mainID := 0; m.items := items; m.click := click; m.key := key; @@ -479,18 +639,18 @@ BEGIN RETURN m END create; - +(* PROCEDURE Redraw*; BEGIN redraw := TRUE END Redraw; - +*) PROCEDURE init* (_resetTimer: tProc); VAR i: INTEGER; BEGIN - Redraw; + (*Redraw;*) resetTimer := _resetTimer; _open := open; FOR i := 0 TO maxLEVEL DO diff --git a/programs/develop/cedit/SRC/Utils.ob07 b/programs/develop/cedit/SRC/Utils.ob07 index 33bf4115ab..e4580d494b 100644 --- a/programs/develop/cedit/SRC/Utils.ob07 +++ b/programs/develop/cedit/SRC/Utils.ob07 @@ -349,4 +349,9 @@ BEGIN END ptr2str; +PROCEDURE between* (a, b, c: INTEGER): BOOLEAN; + RETURN (a <= b) & (b <= c) +END between; + + END Utils. \ No newline at end of file diff --git a/programs/develop/cedit/SRC/scroll.ob07 b/programs/develop/cedit/SRC/scroll.ob07 index b724844e8c..05ca315197 100644 --- a/programs/develop/cedit/SRC/scroll.ob07 +++ b/programs/develop/cedit/SRC/scroll.ob07 @@ -19,16 +19,17 @@ MODULE Scroll; -IMPORT G := Graph, K := KolibriOS; +IMPORT G := Graph, K := KolibriOS, U := Utils; CONST ScrollIPC* = 0; + Delay* = 40; TYPE tScroll* = RECORD - vertical, Inc*, Dec*, mouse*: BOOLEAN; + vertical, Inc*, Dec*, mouse: BOOLEAN; top*, left*, width*, height*: INTEGER; (* read only *) btnSize, sliderSize: INTEGER; @@ -38,21 +39,24 @@ TYPE PROCEDURE create* (vertical: BOOLEAN; width, height: INTEGER; btnSize, sliderSize: INTEGER; VAR scroll: tScroll); +VAR + res: tScroll; BEGIN - scroll.vertical := vertical; - scroll.Inc := FALSE; - scroll.Dec := FALSE; - scroll.Slider := -1; - scroll.mouse := FALSE; - scroll.left := 0; - scroll.top := 0; - scroll.width := width; - scroll.height := height; - scroll.btnSize := btnSize; - scroll.sliderSize := sliderSize; - scroll.pos := 0; - scroll.maxVal := 0; - scroll.canvas := G.CreateCanvas(width, height) + res.vertical := vertical; + res.Inc := FALSE; + res.Dec := FALSE; + res.Slider := -1; + res.mouse := FALSE; + res.left := 0; + res.top := 0; + res.width := width; + res.height := height; + res.btnSize := btnSize; + res.sliderSize := sliderSize; + res.pos := 0; + res.maxVal := 0; + res.canvas := G.CreateCanvas(width, height); + scroll := res END create; @@ -296,11 +300,6 @@ BEGIN END MouseMove; -PROCEDURE between (a, b, c: INTEGER): BOOLEAN; - RETURN (a <= b) & (b <= c) -END between; - - PROCEDURE SendIPC*; BEGIN K.SendIPC(K.ThreadID(), ScrollIPC) @@ -311,34 +310,32 @@ PROCEDURE MouseDown* (VAR scroll: tScroll; x, y: INTEGER); VAR c, size: INTEGER; BEGIN - DEC(x, scroll.left); - DEC(y, scroll.top); - scroll.mouse := TRUE; - IF between(1, x, scroll.width - 2) & between(1, y, scroll.height - 2) THEN - IF scroll.vertical THEN - c := y; - size := scroll.height - ELSE - c := x; - size := scroll.width - END; - IF between(scroll.btnSize + scroll.pos - 1, c, scroll.btnSize + scroll.pos + scroll.sliderSize - 1) THEN - scroll.pos0 := scroll.pos; - scroll.Slider := c - ELSE - IF between(0, c, scroll.btnSize - 1) THEN + IF ~scroll.mouse THEN + DEC(x, scroll.left); + DEC(y, scroll.top); + scroll.mouse := TRUE; + IF U.between(1, x, scroll.width - 2) & U.between(1, y, scroll.height - 2) THEN + IF scroll.vertical THEN + c := y; + size := scroll.height + ELSE + c := x; + size := scroll.width + END; + IF U.between(scroll.btnSize + scroll.pos - 1, c, scroll.btnSize + scroll.pos + scroll.sliderSize - 1) THEN + scroll.pos0 := scroll.pos; + scroll.Slider := c + ELSIF U.between(0, c, scroll.btnSize - 1) THEN scroll.Dec := TRUE; SendIPC + ELSIF U.between(size - scroll.btnSize, c, size - 1) THEN + scroll.Inc := TRUE; + SendIPC ELSE - IF between(size - scroll.btnSize, c, size - 1) THEN - scroll.Inc := TRUE; - SendIPC - ELSE - setPos(scroll, c - scroll.btnSize - scroll.sliderSize DIV 2); - scroll.pos0 := scroll.pos; - scroll.Slider := c; - paint(scroll) - END + setPos(scroll, c - scroll.btnSize - scroll.sliderSize DIV 2); + scroll.pos0 := scroll.pos; + scroll.Slider := c; + paint(scroll) END END END