1 module pixelperfectengine.concrete.elements.menubar; 2 3 public import pixelperfectengine.concrete.elements.base; 4 public import pixelperfectengine.concrete.popup; 5 6 /** 7 * Implements a menubar, that is ideally contained under the top bar of the window, 8 * and contains a tree-like structure for menus. 9 */ 10 public class MenuBar : WindowElement { 11 private PopUpMenuElement[] menus; 12 //private wstring[] menuNames; 13 private int[] menuWidths; 14 //private PopUpHandler popUpHandler; 15 private int select, usedWidth; 16 public EventDeleg onMenuEvent; 17 /** 18 * Creates a menubar. 19 * Params: 20 * source = The source of the emitted events. 21 * position = The position, where the element should be drawn. 22 * menus = The top level menus, which in turn contain any child menus present if any. 23 * customStyle = A custom stylesheet if used. 24 */ 25 public this(string source, Box position, PopUpMenuElement[] menus, StyleSheet customStyle = null){ 26 this.customStyle = customStyle; 27 this.source = source; 28 this.position = position; 29 //this.popUpHandler = popUpHandler; 30 this.menus = menus; 31 select = -1; 32 menuWidths.length = menus.length + 1; 33 menuWidths[0] = position.left; 34 const int spacing = 2 * getStyleSheet().drawParameters["MenuBarHorizPadding"]; 35 for (size_t i ; i < menus.length ; i++) { 36 menuWidths[i + 1] = menuWidths[i] + menus[i].text.getWidth + spacing; 37 } 38 } 39 public override void draw() { 40 StyleSheet ss = getStyleSheet(); 41 with (parent) { 42 drawFilledBox(position, ss.getColor("window")); 43 drawLine(position.cornerUL, position.cornerUR, ss.getColor("windowascent")); 44 drawLine(position.cornerUL, position.cornerLL, ss.getColor("windowascent")); 45 drawLine(position.cornerLL, position.cornerLR, ss.getColor("windowdescent")); 46 drawLine(position.cornerUR, position.cornerLR, ss.getColor("windowdescent")); 47 } 48 if (select > -1) { 49 parent.drawFilledBox(Box(menuWidths[select], position.top + 1, menuWidths[select + 1], position.bottom - 1), 50 ss.getColor("selection")); 51 } 52 foreach (size_t i, PopUpMenuElement menuItem ; menus) { 53 parent.drawTextSL(Box(menuWidths[i], position.top, menuWidths[i+1], position.bottom), menuItem.text, Point(0,0)); 54 } 55 if (onDraw !is null) { 56 onDraw(); 57 } 58 } 59 private void redirectIncomingEvents(Event ev){ 60 if(onMenuEvent !is null){ 61 onMenuEvent(ev); 62 } 63 } 64 ///Passes mouse click event 65 public override void passMCE(MouseEventCommons mec, MouseClickEvent mce) { 66 if (state != ElementState.Enabled) return; 67 if (mce.state) { 68 for (int i ; i < menus.length ; i++) { 69 if (menuWidths[i] < mce.x && menuWidths[i + 1] > mce.x) { 70 select = i; 71 draw; 72 Coordinate c = parent.getAbsolutePosition(this); 73 parent.addPopUpElement(new PopUpMenu(menus[i].getSubElements, source, &redirectIncomingEvents), c.left + 74 menuWidths[i], c.bottom); 75 super.passMCE(mec, mce); 76 return; 77 } 78 } 79 } 80 select = -1; 81 super.passMCE(mec, mce); 82 } 83 ///Passes mouse move event 84 public override void passMME(MouseEventCommons mec, MouseMotionEvent mme) { 85 if (position.isBetween(mme.x, mme.y)) { 86 for (int i ; i < menus.length ; i++) { 87 if (menuWidths[i] < mme.x && menuWidths[i + 1] > mme.x) { 88 select = i; 89 draw; 90 return; 91 } 92 } 93 } 94 select = -1; 95 draw; 96 super.passMME(mec, mme); 97 } 98 ///Called when an object loses focus. 99 public override void focusTaken() { 100 select = -1; 101 super.focusTaken(); 102 } 103 }