mirror of https://github.com/buggins/dlangui.git
menu refactoring
This commit is contained in:
parent
d9df28a02c
commit
a8ddcd9c4f
|
@ -54,10 +54,19 @@ extern (C) int UIAppMain(string[] args) {
|
|||
fileItem.add(new Action(10, "Open..."d));
|
||||
fileItem.add(new Action(11, "Save..."d));
|
||||
fileItem.add(new Action(12, "Exit"d));
|
||||
MenuItem editItem = new MenuItem(new Action(2, "Edit"d));
|
||||
editItem.add(new Action(20, "Copy"d));
|
||||
editItem.add(new Action(21, "Paste"d));
|
||||
editItem.add(new Action(22, "Cut"d));
|
||||
MenuItem windowItem = new MenuItem(new Action(3, "Window"d));
|
||||
windowItem.add(new Action(30, "Preferences"d));
|
||||
MenuItem helpItem = new MenuItem(new Action(4, "Help"d));
|
||||
helpItem.add(new Action(40, "View Help"d));
|
||||
helpItem.add(new Action(41, "About"d));
|
||||
mainMenuItems.add(fileItem);
|
||||
mainMenuItems.add(new Action(2, "Edit"d));
|
||||
mainMenuItems.add(new Action(3, "Window"d));
|
||||
mainMenuItems.add(new Action(4, "Help"d));
|
||||
mainMenuItems.add(editItem);
|
||||
mainMenuItems.add(windowItem);
|
||||
mainMenuItems.add(helpItem);
|
||||
MainMenu mainMenu = new MainMenu(mainMenuItems);
|
||||
contentLayout.addChild(mainMenu);
|
||||
|
||||
|
|
|
@ -418,6 +418,7 @@ class Win32Window : Window {
|
|||
/// request window redraw
|
||||
override void invalidate() {
|
||||
InvalidateRect(_hwnd, null, FALSE);
|
||||
UpdateWindow(_hwnd);
|
||||
}
|
||||
|
||||
/// after drawing, call to schedule redraw if animation is active
|
||||
|
|
|
@ -80,6 +80,13 @@ class ListWidget : WidgetGroup, OnScrollHandler {
|
|||
/// item with Selected state, -1 if no such item
|
||||
protected int _selectedItemIndex;
|
||||
|
||||
/// when true, mouse hover selects underlying item
|
||||
protected bool _selectOnHover;
|
||||
/// when true, mouse hover selects underlying item
|
||||
@property bool selectOnHover() { return _selectOnHover; }
|
||||
/// when true, mouse hover selects underlying item
|
||||
@property ListWidget selectOnHover(bool select) { _selectOnHover = select; return this; }
|
||||
|
||||
/// returns rectangle for item (not scrolled, first item starts at 0,0)
|
||||
Rect itemRectNoScroll(int index) {
|
||||
Rect res;
|
||||
|
@ -173,6 +180,10 @@ class ListWidget : WidgetGroup, OnScrollHandler {
|
|||
}
|
||||
}
|
||||
|
||||
/// override to handle change of selection
|
||||
protected void selectionChanged(int index, int previouslySelectedItem = -1, MouseEvent event = null) {
|
||||
}
|
||||
|
||||
protected void selectItem(int index) {
|
||||
if (_selectedItemIndex == index)
|
||||
return;
|
||||
|
@ -475,9 +486,13 @@ class ListWidget : WidgetGroup, OnScrollHandler {
|
|||
itemrc.top += rc.top - scrollOffset.y;
|
||||
itemrc.bottom += rc.top - scrollOffset.y;
|
||||
if (itemrc.isPointInside(Point(event.x, event.y))) {
|
||||
if (event.flags & (MouseFlag.LButton || MouseFlag.RButton)) {
|
||||
if ((event.flags & (MouseFlag.LButton || MouseFlag.RButton)) || _selectOnHover) {
|
||||
if (_selectedItemIndex == i)
|
||||
return true;
|
||||
int prevSelection = _selectedItemIndex;
|
||||
selectItem(i);
|
||||
setHoverItem(-1);
|
||||
selectionChanged(_selectedItemIndex, prevSelection, event);
|
||||
} else
|
||||
setHoverItem(i);
|
||||
}
|
||||
|
|
|
@ -77,117 +77,64 @@ class MenuItemWidget : HorizontalLayout {
|
|||
addChild(_label);
|
||||
trackHover = true;
|
||||
}
|
||||
|
||||
/// process mouse event; return true if event is processed by widget.
|
||||
override bool onMouseEvent(MouseEvent event) {
|
||||
Log.d("onMouseEvent ", id, " ", event.action, " (", event.x, ",", event.y, ")");
|
||||
// support onClick
|
||||
if (_handler !is null) {
|
||||
if (event.action == MouseAction.ButtonDown && event.button == MouseButton.Left) {
|
||||
setState(State.Selected);
|
||||
_handler.onItemMouseDown(this, event);
|
||||
return true;
|
||||
}
|
||||
if (event.action == MouseAction.ButtonUp && event.button == MouseButton.Left) {
|
||||
resetState(State.Selected);
|
||||
_handler.onItemMouseDown(this, event);
|
||||
return true;
|
||||
}
|
||||
/*
|
||||
if (event.action == MouseAction.ButtonUp && event.button == MouseButton.Left) {
|
||||
resetState(State.Pressed);
|
||||
_onClickListener(this);
|
||||
return true;
|
||||
}
|
||||
if (event.action == MouseAction.FocusOut || event.action == MouseAction.Cancel) {
|
||||
resetState(State.Pressed);
|
||||
resetState(State.Hovered);
|
||||
return true;
|
||||
}
|
||||
if (event.action == MouseAction.FocusIn) {
|
||||
setState(State.Pressed);
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
}
|
||||
return super.onMouseEvent(event);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class MainMenu : HorizontalLayout, MenuItemWidgetHandler {
|
||||
class MenuWidgetBase : ListWidget {
|
||||
protected MenuItem _item;
|
||||
protected PopupMenu _openedMenu;
|
||||
protected PopupWidget _openedPopup;
|
||||
protected MenuItemWidget _openedMenu;
|
||||
|
||||
|
||||
|
||||
override protected bool onItemMouseDown(MenuItemWidget itemWidget, MouseEvent ev) {
|
||||
PopupMenu popupMenu = new PopupMenu(itemWidget.item);
|
||||
PopupWidget popup = window.showPopup(popupMenu, itemWidget, PopupAlign.Below);
|
||||
ev.track(popupMenu);
|
||||
return true;
|
||||
}
|
||||
override protected bool onItemMouseUp(MenuItemWidget itemWidget, MouseEvent ev) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
protected bool onItemClick(Widget w) {
|
||||
MenuItemWidget itemWidget = cast(MenuItemWidget)w;
|
||||
Log.d("onItemClick ", w.id);
|
||||
window.showPopup(new PopupMenu(itemWidget.item), itemWidget, PopupAlign.Below);
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
this(MenuItem item) {
|
||||
id = "MAIN_MENU";
|
||||
styleId = "MAIN_MENU";
|
||||
this(MenuItem item, Orientation orientation) {
|
||||
_item = item;
|
||||
for (int i = 0; i < item.subitemCount; i++) {
|
||||
MenuItemWidget subitem = new MenuItemWidget(item.subitem(i));
|
||||
//subitem.onClickListener = &onItemClick;
|
||||
subitem.handler = this;
|
||||
addChild(subitem);
|
||||
}
|
||||
addChild((new Widget()).layoutWidth(FILL_PARENT));
|
||||
}
|
||||
}
|
||||
|
||||
class PopupMenu : ListWidget, MenuItemWidgetHandler {
|
||||
protected MenuItem _item;
|
||||
this(MenuItem item) {
|
||||
this.orientation = orientation;
|
||||
id = "popup_menu";
|
||||
styleId = "POPUP_MENU";
|
||||
_item = item;
|
||||
WidgetListAdapter adapter = new WidgetListAdapter();
|
||||
for (int i=0; i < _item.subitemCount; i++) {
|
||||
MenuItem subitem = _item.subitem(i);
|
||||
MenuItemWidget widget = new MenuItemWidget(subitem);
|
||||
widget.handler = this;
|
||||
//widget.handler = this;
|
||||
adapter.widgets.add(widget);
|
||||
}
|
||||
ownAdapter = adapter;
|
||||
}
|
||||
|
||||
override protected bool onItemMouseDown(MenuItemWidget itemWidget, MouseEvent ev) {
|
||||
/// override to handle change of selection
|
||||
override protected void selectionChanged(int index, int previouslySelectedItem = -1, MouseEvent event = null) {
|
||||
MenuItemWidget itemWidget = index >= 0 ? cast(MenuItemWidget)_adapter.itemWidget(index) : null;
|
||||
if (itemWidget.item.isSubmenu()) {
|
||||
if (_openedPopup !is null)
|
||||
_openedPopup.close();
|
||||
PopupMenu popupMenu = new PopupMenu(itemWidget.item);
|
||||
PopupWidget popup = window.showPopup(popupMenu, itemWidget, PopupAlign.Below);
|
||||
ev.track(popupMenu);
|
||||
if (event !is null && (event.flags & (MouseFlag.LButton || MouseFlag.RButton)))
|
||||
event.track(popupMenu);
|
||||
_openedPopup = popup;
|
||||
_openedMenu = popupMenu;
|
||||
selectOnHover = true;
|
||||
} else {
|
||||
// normal item
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
override protected bool onItemMouseUp(MenuItemWidget itemWidget, MouseEvent ev) {
|
||||
if (itemWidget.item.isSubmenu()) {
|
||||
} else {
|
||||
// normal item
|
||||
// TODO: action
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class MainMenu : MenuWidgetBase {
|
||||
|
||||
this(MenuItem item) {
|
||||
super(item, Orientation.Horizontal);
|
||||
id = "MAIN_MENU";
|
||||
styleId = "MAIN_MENU";
|
||||
}
|
||||
}
|
||||
|
||||
class PopupMenu : MenuWidgetBase {
|
||||
|
||||
this(MenuItem item) {
|
||||
super(item, Orientation.Vertical);
|
||||
id = "POPUP_MENU";
|
||||
styleId = "POPUP_MENU";
|
||||
selectOnHover = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,10 @@ class PopupWidget : LinearLayout {
|
|||
override void measure(int parentWidth, int parentHeight) {
|
||||
super.measure(parentWidth, parentHeight);
|
||||
}
|
||||
/// close and destroy popup
|
||||
void close() {
|
||||
window.removePopup(this);
|
||||
}
|
||||
|
||||
/// Set widget rectangle to specified value and layout widget contents. (Step 2 of two phase layout).
|
||||
override void layout(Rect rc) {
|
||||
|
|
Loading…
Reference in New Issue