1 module PixelPerfectEngine.concrete.elements.panel; 2 3 import PixelPerfectEngine.concrete.elements.base; 4 5 import PixelPerfectEngine.system.etc : clamp, cmpObjPtr; 6 7 import collections.linkedlist; 8 9 10 /** 11 * Panel for grouping elements. 12 * Does not directly handle elements, instead relies on blitter transparency. However, can handle 13 * the state of the elements. 14 */ 15 public class Panel : WindowElement, ElementContainer { 16 alias WESet = LinkedList!(WindowElement, false, "a is b"); 17 protected WESet subElems; ///Contains all elements within the panel 18 protected sizediff_t focusedElem; ///Index of the currently focused element 19 /** 20 * Default CTOR 21 */ 22 public this(Text text, string source, Coordinate coordinates) { 23 position = coordinates; 24 this.text = text; 25 this.source = source; 26 } 27 ///Ditto 28 public this(dstring text, string source, Coordinate position) { 29 this(new Text(text, getStyleSheet().getChrFormatting("panel")), source, position); 30 } 31 public override void draw() { 32 foreach (key; subElems) { 33 key.draw; 34 } 35 StyleSheet ss = getStyleSheet(); 36 const int textLength = text.getWidth(); 37 const Box offsetEdge = position - (text.font.size / 2); 38 const Box textPos = Box(offsetEdge.left, position.top, offsetEdge.left + textLength, position.top + text.font.size); 39 with (parent) { 40 drawLine(Point(offsetEdge.left + textLength, offsetEdge.top), offsetEdge.cornerUR, ss.getColor("windowAscent")); 41 drawLine(offsetEdge.cornerUL, offsetEdge.cornerLL, ss.getColor("windowAscent")); 42 drawLine(offsetEdge.cornerLL, offsetEdge.cornerLR, ss.getColor("windowAscent")); 43 drawLine(offsetEdge.cornerUR, offsetEdge.cornerLR, ss.getColor("windowAscent")); 44 drawTextSL(textPos, text, Point(0, 0)); 45 } 46 if (state == ElementState.Disabled) { 47 parent.bitBLTPattern(position, ss.getImage("ElementDisabledPtrn")); 48 } 49 } 50 51 public Coordinate getAbsolutePosition(WindowElement sender) { 52 return parent.getAbsolutePosition(sender); // TODO: implement 53 } 54 55 /** 56 * Gives focus to the element if applicable 57 */ 58 public void requestFocus(WindowElement sender) { 59 subElems[focusedElem].focusTaken(); 60 focusedElem = subElems.which(sender); 61 subElems[focusedElem].focusGiven(); 62 } 63 ///Called when an object receives focus. 64 public override void focusGiven() { 65 if(subElems.length) subElems[focusedElem].focusGiven(); 66 flags |= IS_FOCUSED; 67 draw; 68 } 69 ///Called when an object loses focus. 70 public override void focusTaken() { 71 subElems[focusedElem].focusTaken(); 72 flags &= ~IS_FOCUSED; 73 draw; 74 } 75 ///Cycles the focus on a single element. 76 ///Returns -1 if end is reached, or the number of remaining elements that 77 ///are cycleable in the direction. 78 public override int cycleFocus(int direction) { 79 if (focusedElem + direction < 0 || focusedElem + direction >= subElems.length) { 80 return -1; 81 } else { 82 if (subElems.length) { 83 const int result = subElems[focusedElem].cycleFocus(direction); 84 if (result == -1) { 85 subElems[focusedElem].focusTaken(); 86 focusedElem += direction; 87 subElems[focusedElem].focusGiven(); 88 } 89 } 90 return direction > 1 ? cast(int)(subElems.length - focusedElem) : cast(int)focusedElem; 91 } 92 } 93 94 public void drawLine(Point from, Point to, ubyte color) @trusted { 95 parent.drawLine(from, to, color); 96 } 97 98 public void drawLinePattern(Point from, Point to, ubyte[] pattern) @trusted { 99 parent.drawLinePattern(from, to, pattern); 100 } 101 102 public void drawBox(Coordinate target, ubyte color) @trusted { 103 parent.drawBox(target, color); 104 } 105 106 public void drawBoxPattern(Coordinate target, ubyte[] pattern) @trusted { 107 parent.drawBoxPattern(target, pattern); 108 } 109 110 public void drawFilledBox(Coordinate target, ubyte color) @trusted { 111 parent.drawFilledBox(target, color); 112 } 113 114 public void bitBLT(Point target, ABitmap source) @trusted { 115 parent.bitBLT(target, source); 116 } 117 118 public void bitBLT(Point target, ABitmap source, Coordinate slice) @trusted { 119 parent.bitBLT(target, source, slice); 120 } 121 122 public void bitBLTPattern(Coordinate target, ABitmap pattern) @trusted { 123 parent.bitBLTPattern(target, pattern); 124 } 125 126 public void xorBitBLT(Coordinate target, ABitmap pattern) @trusted { 127 parent.xorBitBLT(target, pattern); 128 } 129 130 public void xorBitBLT(Coordinate target, ubyte color) @trusted { 131 parent.xorBitBLT(target, color); 132 } 133 134 public void fill(Point target, ubyte color, ubyte background = 0) @trusted { 135 parent.fill(target, color, background); 136 } 137 138 public void drawTextSL(Coordinate target, Text text, Point offset) @trusted { 139 parent.drawTextSL(target, text, offset); 140 } 141 142 public void drawTextML(Coordinate target, Text text, Point offset) @trusted { 143 parent.drawTextML(target, text, offset); 144 } 145 146 public void clearArea(Coordinate target) @trusted { 147 parent.clearArea(target); 148 } 149 /** 150 * Sets the cursor to the given type on request. 151 */ 152 public void requestCursor(CursorType type) { 153 parent.requestCursor(type); 154 } 155 /** 156 * Puts a PopUpElement on the GUI. 157 */ 158 public void addPopUpElement(PopUpElement p) { 159 parent.addPopUpElement(p); 160 } 161 /** 162 * Puts a PopUpElement on the GUI at the given position. 163 */ 164 public void addPopUpElement(PopUpElement p, int x, int y) { 165 parent.addPopUpElement(p, x, y); 166 } 167 /** 168 * Ends the popup session and closes all popups. 169 */ 170 public void endPopUpSession(PopUpElement p) { 171 parent.endPopUpSession(p); 172 } 173 /** 174 * Closes a single popup element. 175 */ 176 public void closePopUp(PopUpElement p) { 177 parent.closePopUp(p); 178 } 179 }