diff --git a/examples/editlinelist/.gitignore b/examples/editlinelist/.gitignore new file mode 100644 index 00000000..eec6d038 --- /dev/null +++ b/examples/editlinelist/.gitignore @@ -0,0 +1,6 @@ +.dub +docs.json +__dummy.html +*.o +*.obj +__test__*__ diff --git a/examples/editlinelist/dub.json b/examples/editlinelist/dub.json new file mode 100644 index 00000000..83be37a2 --- /dev/null +++ b/examples/editlinelist/dub.json @@ -0,0 +1,51 @@ +{ + "name": "editlinelist", + "authors": [ + "http://lemming.life" + ], + "description": "example of an edit line list in dlangui", + "license": "Boost", + + "targetPath": "bin", + "targetType": "executable", + "targetName": "editlinelist", + + "stringImportPaths": ["views", "views/res", "views/res/i18n", "views/res/mdpi"], + + "sourceFiles-windows": ["$PACKAGE_DIR/src/win_app.def"], + + "versions": ["ForceLogs"], + + "dependencies": { + "dlangui": {"path": "../../"} + }, + "configurations" : [ + { + "name" : "default", + }, + { + "name" : "console", + "subConfigurations" : { + "dlangui" : "console" + } + }, + { + "name" : "sdl", + "subConfigurations" : { + "dlangui" : "sdl" + } + }, + { + "name" : "x11", + "subConfigurations" : { + "dlangui" : "x11" + } + }, + { + "name" : "minimal", + "subConfigurations" : { + "dlangui" : "minimal" + } + } + ] +} diff --git a/examples/editlinelist/source/app.d b/examples/editlinelist/source/app.d new file mode 100644 index 00000000..acc4a4c0 --- /dev/null +++ b/examples/editlinelist/source/app.d @@ -0,0 +1,154 @@ +module app; +import dlangui; + +mixin APP_ENTRY_POINT; + +/// Entry point for dlangui based application +extern (C) int UIAppMain(string[] args) { + auto view = new View("EditLine List Example"); + return Platform.instance.enterMessageLoop(); +} + +// Our View example +class View { + this(dstring aTitle) { + // Prep the window + auto window = Platform.instance.createWindow(aTitle, null, WindowFlag.Resizable, 640, 480); + window.mainWidget = parseML(q{ + VerticalLayout { + margins: 5pt; + layoutWidth: fill + layoutHeight: fill + } + }); + + // Prep the adapter and list + auto listAdapter = new WidgetListAdapterKeysMouse(); + auto editLineList = new EditLineList(); + editLineList.layoutWidth(FILL_PARENT); + editLineList.layoutHeight(FILL_PARENT); + editLineList.ownAdapter = listAdapter; + window.mainWidget.addChild(editLineList); + + // Add some EditLineForList objects + import std.conv : to; + listAdapter.add(new EditLineForList("editLine2", "Double click me! You can select a word."d)); + listAdapter.add(new EditLineForList("editLine1", "Use left/right keys to move cursor left/right of selection."d)); + listAdapter.add(new EditLineForList("editLine0", "Use up/down keys to move to the next edit line."d)); + listAdapter.add(new EditLineForList("editLine3", "You can also do select all via keys, and do other edit line features."d)); + listAdapter.add(new EditLineForList("editLine3", "The edit line list could be used to edit data rapidly."d)); + for (int i=4; i<64; ++i) { + listAdapter.add(new EditLineForList("editLine" ~ to!string(i), "editLine "d ~ to!dstring(i))); + } + + // Event handling example + editLineList.itemSelected = delegate(Widget source, int itemIndex) { + auto item = cast(EditLineForList) listAdapter.itemWidget(itemIndex); + window.windowCaption = aTitle ~ " | Selected: "d ~ item.idAsDstring; + return true; + }; + + window.show; + } // End this(dstring aTitle) + +} // End class View + +// BEGIN EditLineList, adapter, and EditLineForList +// ------------------------------------------------------------------------- +class EditLineList : ListWidget { + override bool onKeyEvent(KeyEvent event) { + if (itemCount == 0 || _selectedItemIndex < 0) return false; + + int navigationDelta = 0; + if (event.action == KeyAction.KeyDown) { + if (orientation == Orientation.Vertical) { + if (event.keyCode == KeyCode.DOWN) + navigationDelta = 1; + else if (event.keyCode == KeyCode.UP) + navigationDelta = -1; + } + } + + auto item = cast(EditLineForList) _adapter.itemWidget(_selectedItemIndex); + + if (navigationDelta != 0) { + moveSelection(navigationDelta); + item = cast(EditLineForList) _adapter.itemWidget(_selectedItemIndex); // because the item changed + item.allAndFocus(); // Do a select all on the EditLine + return true; + } + + if (item.onKeyEvent(event)) { + invalidate(); + return true; + } + + return super.onKeyEvent(event); + } // End onKeyEvent(KeyEvent event) + + + // Modify the behavior of the mouse on the list slightly. + override bool onMouseEvent(MouseEvent event) { + super.onMouseEvent(event); + if (_selectedItemIndex == -1) { return false; } + _adapter.itemWidget(_selectedItemIndex).onMouseEvent(event); + return true; + } + +} // End EditLineList + +// Adapter that can use keys and mouse events. +class WidgetListAdapterKeysMouse : WidgetListAdapter { + override @property bool wantKeyEvents() { return true; } + override @property bool wantMouseEvents() { return true; } +} + +// EditLine with slight modifications for list environment. +class EditLineForList : EditLine { + + this(string id, dstring text = null) { + this.id = id; + this.text = text; + } + + void allAndFocus() { + bool focused = true; + bool receivedFocusFromKeyboard = true; + handleFocusChange(focused, receivedFocusFromKeyboard); + } + + override bool onKeyEvent(KeyEvent event) { + import std.stdio : writeln; + bool focused = true; + bool receivedFocusFromKeyboard = false; + handleFocusChange(focused, receivedFocusFromKeyboard); + + // Move the cursor to the left or right of selection. + if (_selectionRange.end.pos - _selectionRange.start.pos > 0) { + if (event.keyCode == KeyCode.LEFT) { + _caretPos.pos = _selectionRange.start.pos; + _selectionRange.start.pos = _caretPos.pos; + _selectionRange.end.pos = _caretPos.pos; + ensureCaretVisible(); + return true; + } else if (event.keyCode == KeyCode.RIGHT) { + _caretPos.pos = _selectionRange.end.pos; + _selectionRange.start.pos = _caretPos.pos; + _selectionRange.end.pos = _caretPos.pos; + ensureCaretVisible(); + return true; + } + } + + super.onKeyEvent(event); + return true; + } // End onKeyEvent(KeyEvent event) + + + dstring idAsDstring() { + import std.conv : to; + return to!dstring(id); + } +} // End EditLineForList + +// END EditLineList, adapter, and EditLineForList \ No newline at end of file