diff --git a/src/dlangui/core/editable.d b/src/dlangui/core/editable.d
index c511f8ed..6ca7f2ae 100644
--- a/src/dlangui/core/editable.d
+++ b/src/dlangui/core/editable.d
@@ -1605,9 +1605,9 @@ struct LineIcons {
LineIcon item = _items[i];
if (item.type != type)
continue;
- if (!firstBefore && item.line < line)
+ if (!firstBefore && item.line >= line)
firstBefore = item;
- else if (!firstAfter && item.line > line)
+ else if (!firstAfter && item.line < line)
firstAfter = item;
}
} else {
@@ -1616,7 +1616,7 @@ struct LineIcons {
LineIcon item = _items[i];
if (item.type != type)
continue;
- if (!firstBefore && item.line < line)
+ if (!firstBefore && item.line <= line)
firstBefore = item;
else if (!firstAfter && item.line > line)
firstAfter = item;
diff --git a/src/dlangui/core/events.d b/src/dlangui/core/events.d
index 219e560c..179050d5 100644
--- a/src/dlangui/core/events.d
+++ b/src/dlangui/core/events.d
@@ -135,7 +135,7 @@ class Action {
/// optional string parameter
protected string _stringParam;
/// optional long parameter
- protected long _longParam;
+ protected long _longParam = long.min;
/// optional object parameter
protected Object _objectParam;
diff --git a/src/dlangui/widgets/editors.d b/src/dlangui/widgets/editors.d
index 7d8ee52c..3e2f789f 100644
--- a/src/dlangui/widgets/editors.d
+++ b/src/dlangui/widgets/editors.d
@@ -200,13 +200,15 @@ const Action ACTION_EDITOR_TOGGLE_REPLACE_MODE = (new Action(EditorActions.Toggl
const Action ACTION_EDITOR_SELECT_ALL = (new Action(EditorActions.SelectAll, KeyCode.KEY_A, KeyFlag.Control));
const Action ACTION_EDITOR_TOGGLE_LINE_COMMENT = (new Action(EditorActions.ToggleLineComment, KeyCode.KEY_DIVIDE, KeyFlag.Control));
const Action ACTION_EDITOR_TOGGLE_BLOCK_COMMENT = (new Action(EditorActions.ToggleBlockComment, KeyCode.KEY_DIVIDE, KeyFlag.Control | KeyFlag.Shift));
-const Action ACTION_EDITOR_TOGGLE_BOOKMARK = (new Action(EditorActions.ToggleBookmark, "ACTION_EDITOR_TOGGLE_BOOKMARK"c));
-const Action ACTION_EDITOR_GOTO_NEXT_BOOKMARK = (new Action(EditorActions.GoToNextBookmark, "ACTION_EDITOR_GOTO_NEXT_BOOKMARK"c));
-const Action ACTION_EDITOR_GOTO_PREVIOUS_BOOKMARK = (new Action(EditorActions.GoToPreviousBookmark, "ACTION_EDITOR_GOTO_PREVIOUS_BOOKMARK"c));
+const Action ACTION_EDITOR_TOGGLE_BOOKMARK = (new Action(EditorActions.ToggleBookmark, "ACTION_EDITOR_TOGGLE_BOOKMARK"c, null, KeyCode.KEY_B, KeyFlag.Control | KeyFlag.Shift));
+const Action ACTION_EDITOR_GOTO_NEXT_BOOKMARK = (new Action(EditorActions.GoToNextBookmark, "ACTION_EDITOR_GOTO_NEXT_BOOKMARK"c, null, KeyCode.DOWN, KeyFlag.Control | KeyFlag.Shift));
+const Action ACTION_EDITOR_GOTO_PREVIOUS_BOOKMARK = (new Action(EditorActions.GoToPreviousBookmark, "ACTION_EDITOR_GOTO_PREVIOUS_BOOKMARK"c, null, KeyCode.UP, KeyFlag.Control | KeyFlag.Shift));
const Action[] STD_EDITOR_ACTIONS = [ACTION_EDITOR_INSERT_NEW_LINE, ACTION_EDITOR_PREPEND_NEW_LINE,
ACTION_EDITOR_APPEND_NEW_LINE, ACTION_EDITOR_DELETE_LINE, ACTION_EDITOR_TOGGLE_REPLACE_MODE,
- ACTION_EDITOR_SELECT_ALL, ACTION_EDITOR_TOGGLE_LINE_COMMENT, ACTION_EDITOR_TOGGLE_BLOCK_COMMENT];
+ ACTION_EDITOR_SELECT_ALL, ACTION_EDITOR_TOGGLE_LINE_COMMENT, ACTION_EDITOR_TOGGLE_BLOCK_COMMENT,
+ ACTION_EDITOR_TOGGLE_BOOKMARK, ACTION_EDITOR_GOTO_NEXT_BOOKMARK, ACTION_EDITOR_GOTO_PREVIOUS_BOOKMARK
+];
/// base for all editor widgets
class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemActionHandler {
@@ -238,9 +240,13 @@ class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemAction
protected uint _selectionColorNormal = 0xD060A0FF;
protected uint _leftPaneBackgroundColor = 0xF4F4F4;
protected uint _leftPaneBackgroundColor2 = 0xFFFFFF;
- protected uint _leftPaneBackgroundColor3 = 0xC0C0C0;
+ protected uint _leftPaneBackgroundColor3 = 0xE0E0E0;
protected uint _leftPaneLineNumberColor = 0x4060D0;
protected uint _leftPaneLineNumberBackgroundColor = 0xF0F0F0;
+ protected uint _colorIconBreakpoint = 0xFF0000;
+ protected uint _colorIconBookmark = 0x0000FF;
+ protected uint _colorIconError = 0x80FF0000;
+
protected uint _caretColor = 0x000000;
protected uint _caretColorReplace = 0x808080FF;
protected uint _matchingBracketHightlightColor = 0x60FFE0B0;
@@ -291,8 +297,32 @@ class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemAction
buf.fillRect(rc, _leftPaneBackgroundColor2);
}
+ protected void drawLeftPaneIcon(DrawBuf buf, Rect rc, LineIcon icon) {
+ if (!icon)
+ return;
+ if (icon.type == LineIconType.error) {
+ buf.fillRect(rc, _colorIconError);
+ } else if (icon.type == LineIconType.bookmark) {
+ int dh = rc.height / 4;
+ rc.top += dh;
+ rc.bottom -= dh;
+ buf.fillRect(rc, _colorIconBookmark);
+ } else if (icon.type == LineIconType.breakpoint) {
+ int dh = rc.height / 8;
+ rc.top += dh;
+ rc.bottom -= dh;
+ int dw = rc.width / 4;
+ rc.left += dw;
+ rc.right -= dw;
+ buf.fillRect(rc, _colorIconBreakpoint);
+ }
+ }
+
protected void drawLeftPaneIcons(DrawBuf buf, Rect rc, int line) {
buf.fillRect(rc, _leftPaneBackgroundColor3);
+ drawLeftPaneIcon(buf, rc, content.lineIcons.findByLineAndType(line, LineIconType.error));
+ drawLeftPaneIcon(buf, rc, content.lineIcons.findByLineAndType(line, LineIconType.bookmark));
+ drawLeftPaneIcon(buf, rc, content.lineIcons.findByLineAndType(line, LineIconType.breakpoint));
}
protected void drawLeftPaneModificationMarks(DrawBuf buf, Rect rc, int line) {
@@ -320,6 +350,73 @@ class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemAction
fnt.drawText(buf, x, y, s, _leftPaneLineNumberColor);
}
+ protected bool onLeftPaneMouseClick(MouseEvent event) {
+ return false;
+ }
+
+ protected bool handleLeftPaneFoldingMouseClick(MouseEvent event, Rect rc, int line) {
+ return true;
+ }
+
+ protected bool handleLeftPaneModificationMarksMouseClick(MouseEvent event, Rect rc, int line) {
+ return true;
+ }
+
+ protected bool handleLeftPaneLineNumbersMouseClick(MouseEvent event, Rect rc, int line) {
+ return true;
+ }
+
+ protected MenuItem getLeftPaneIconsPopupMenu(int line) {
+ return null;
+ }
+
+ protected bool handleLeftPaneIconsMouseClick(MouseEvent event, Rect rc, int line) {
+ if (event.button == MouseButton.Right) {
+ MenuItem menu = getLeftPaneIconsPopupMenu(line);
+ if (menu) {
+ if (menu.openingSubmenu.assigned)
+ if (!menu.openingSubmenu(_popupMenu))
+ return true;
+ menu.updateActionState(this);
+ PopupMenu popupMenu = new PopupMenu(menu);
+ popupMenu.menuItemAction = this;
+ PopupWidget popup = window.showPopup(popupMenu, this, PopupAlign.Point | PopupAlign.Right, event.x, event.y);
+ popup.flags = PopupFlags.CloseOnClickOutside;
+ }
+ return true;
+ }
+ return true;
+ }
+
+ protected bool handleLeftPaneMouseClick(MouseEvent event, Rect rc, int line) {
+ rc.right -= 3;
+ if (_foldingWidth) {
+ Rect rc2 = rc;
+ rc.right = rc2.left = rc2.right - _foldingWidth;
+ if (event.x >= rc2.left && event.x < rc2.right)
+ return handleLeftPaneFoldingMouseClick(event, rc2, line);
+ }
+ if (_modificationMarksWidth) {
+ Rect rc2 = rc;
+ rc.right = rc2.left = rc2.right - _modificationMarksWidth;
+ if (event.x >= rc2.left && event.x < rc2.right)
+ return handleLeftPaneModificationMarksMouseClick(event, rc2, line);
+ }
+ if (_lineNumbersWidth) {
+ Rect rc2 = rc;
+ rc.right = rc2.left = rc2.right - _lineNumbersWidth;
+ if (event.x >= rc2.left && event.x < rc2.right)
+ return handleLeftPaneLineNumbersMouseClick(event, rc2, line);
+ }
+ if (_iconsWidth) {
+ Rect rc2 = rc;
+ rc.right = rc2.left = rc2.right - _iconsWidth;
+ if (event.x >= rc2.left && event.x < rc2.right)
+ return handleLeftPaneIconsMouseClick(event, rc2, line);
+ }
+ return true;
+ }
+
protected void drawLeftPane(DrawBuf buf, Rect rc, int line) {
// override for custom drawn left pane
buf.fillRect(rc, _leftPaneBackgroundColor);
@@ -836,6 +933,9 @@ class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemAction
_leftPaneBackgroundColor3 = style.customColor("editor_left_pane_background3");
_leftPaneLineNumberColor = style.customColor("editor_left_pane_line_number_text");
_leftPaneLineNumberBackgroundColor = style.customColor("editor_left_pane_line_number_background");
+ _colorIconBreakpoint = style.customColor("editor_left_pane_line_icon_color_breakpoint", 0xFF0000);
+ _colorIconBookmark = style.customColor("editor_left_pane_line_icon_color_bookmark", 0x0000FF);
+ _colorIconError = style.customColor("editor_left_pane_line_icon_color_error", 0x80FF0000);
_matchingBracketHightlightColor = style.customColor("editor_matching_bracket_highlight");
super.onThemeChanged();
}
@@ -1307,7 +1407,8 @@ class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemAction
return true;
case EditorActions.ToggleBookmark:
if (_content.multiline) {
- _content.lineIcons.toggleBookmark(_selectionRange.end.line);
+ int line = a.longParam >= 0 ? cast(int)a.longParam : _selectionRange.end.line;
+ _content.lineIcons.toggleBookmark(line);
return true;
}
return false;
@@ -1467,6 +1568,11 @@ class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemAction
override bool onMouseEvent(MouseEvent event) {
//Log.d("onMouseEvent ", id, " ", event.action, " (", event.x, ",", event.y, ")");
// support onClick
+ if (event.action == MouseAction.ButtonDown && event.x < _clientRect.left && event.x >= _clientRect.left - _leftPaneWidth) {
+ setFocus();
+ if (onLeftPaneMouseClick(event))
+ return true;
+ }
if (event.action == MouseAction.ButtonDown && event.button == MouseButton.Left) {
setFocus();
startCaretBlinking();
@@ -2408,6 +2514,38 @@ class EditBox : EditWidgetBase {
drawCaret(buf);
}
+ protected override bool onLeftPaneMouseClick(MouseEvent event) {
+ if (_leftPaneWidth <= 0)
+ return false;
+ Rect rc = _clientRect;
+ FontRef font = font();
+ int i = _firstVisibleLine;
+ int lc = lineCount;
+ for (;;) {
+ Rect lineRect = rc;
+ lineRect.left = _clientRect.left - _leftPaneWidth;
+ lineRect.right = _clientRect.left;
+ lineRect.bottom = lineRect.top + _lineHeight;
+ if (lineRect.top >= _clientRect.bottom)
+ break;
+ if (event.y >= lineRect.top && event.y < lineRect.bottom) {
+ return handleLeftPaneMouseClick(event, lineRect, i);
+ }
+ i++;
+ rc.top += _lineHeight;
+ }
+ return false;
+ }
+
+ override protected MenuItem getLeftPaneIconsPopupMenu(int line) {
+ MenuItem menu = new MenuItem();
+ Action toggleBookmarkAction = ACTION_EDITOR_TOGGLE_BOOKMARK.clone();
+ toggleBookmarkAction.longParam = line;
+ toggleBookmarkAction.objectParam = this;
+ MenuItem item = menu.add(toggleBookmarkAction);
+ return menu;
+ }
+
}
/// Read only edit box for displaying logs with lines append operation
diff --git a/views/res/theme_dark.xml b/views/res/theme_dark.xml
index aef2d7cb..f9ff5f51 100644
--- a/views/res/theme_dark.xml
+++ b/views/res/theme_dark.xml
@@ -15,6 +15,9 @@
+
+
+
diff --git a/views/res/theme_default.xml b/views/res/theme_default.xml
index 21aba152..58f23dff 100644
--- a/views/res/theme_default.xml
+++ b/views/res/theme_default.xml
@@ -14,9 +14,12 @@
-
+
+
+
+