menu refactoring

This commit is contained in:
Vadim Lopatin 2014-04-14 21:53:53 +04:00
parent d9df28a02c
commit a8ddcd9c4f
5 changed files with 69 additions and 93 deletions

View File

@ -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);

View File

@ -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

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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) {