1 /* 2 * Copyright (C) 2015-2017, by Laszlo Szeremi under the Boost license. 3 * 4 * Pixel Perfect Engine, concrete.elements module 5 */ 6 7 module PixelPerfectEngine.concrete.elements; 8 9 import PixelPerfectEngine.graphics.bitmap; 10 import PixelPerfectEngine.graphics.draw; 11 import PixelPerfectEngine.system.etc; 12 import PixelPerfectEngine.system.inputHandler; 13 import std.algorithm; 14 import std.stdio; 15 import std.conv; 16 import PixelPerfectEngine.concrete.stylesheet; 17 18 abstract class WindowElement{ 19 public ActionListener[] al; 20 private wstring text; 21 private string source; 22 private Coordinate position; 23 private int sizeX, sizeY; 24 //public int font; 25 public BitmapDrawer output; 26 //public Bitmap16Bit[int] altStyleBrush; 27 public ElementContainer elementContainer; 28 public StyleSheet customStyle; 29 30 public static InputHandler inputHandler; 31 //public static StyleSheet defaultStyle; 32 33 public void onClick(int offsetX, int offsetY, int type = 0){ 34 35 } 36 public void onKey(char c, int type){ 37 38 } 39 public void onScroll(int x, int y, int wX, int wY){ 40 41 } 42 public int getX(){ 43 return sizeX; 44 } 45 public int getY(){ 46 return sizeY; 47 } 48 public Coordinate getPosition(){ 49 return position; 50 } 51 /* 52 * Updates the output. 53 */ 54 public abstract void draw(); 55 56 private void invokeActionEvent(int type, int value, wstring message = ""){ 57 foreach(ActionListener a; al){ 58 //a.actionEvent(source, type, value, message); 59 a.actionEvent(new Event(source, null, null, null, text, value, type)); 60 } 61 } 62 /*private Bitmap16Bit getBrush(int style){ 63 return altStyleBrush.get(style, elementContainer.getStyleBrush(style)); 64 }*/ 65 public wstring getText(){ 66 return text; 67 } 68 public void setText(wstring s){ 69 text = s; 70 draw; 71 } 72 73 public StyleSheet getAvailableStyleSheet(){ 74 if(customStyle is null){ 75 return elementContainer.getStyleSheet(); 76 } 77 return customStyle; 78 } 79 80 public void setCustomStyle(StyleSheet s){ 81 customStyle = s; 82 } 83 84 /*public static void initalizeDefaultStyle(){ 85 defaultStyle = new StyleSheet(); 86 }*/ 87 88 /*public static void setDefaultStyle(StyleSheet s){ 89 defaultStyle = s; 90 }*/ 91 } 92 93 public class Button : WindowElement{ 94 95 private bool isPressed; 96 public int brushPressed, brushNormal; 97 98 public this(wstring text, string source, Coordinate coordinates){ 99 position = coordinates; 100 sizeX = coordinates.getXSize(); 101 sizeY = coordinates.getYSize(); 102 this.text = text; 103 this.source = source; 104 output = new BitmapDrawer(sizeX, sizeY); 105 brushPressed = 1; 106 //draw(); 107 } 108 public override void draw(){ 109 output.drawFilledRectangle(0, position.getXSize()-1, 0,position.getYSize()-1, getAvailableStyleSheet().getColor("window")); 110 if(isPressed){ 111 /*output.drawRectangle(0, sizeX, 0, sizeY, getBrush(brushNormal)); 112 int x = getBrush(brushNormal).getX() / 2, y = getBrush(brushNormal).getY() / 2; 113 output.drawFilledRectangle(x, sizeX - 1 - x, y, sizeY - 1 - y, getBrush(brushNormal).readPixel(x, y));*/ 114 output.drawLine(0, position.getXSize()-1, 0, 0, getAvailableStyleSheet().getColor("windowdescent")); 115 output.drawLine(0, 0, 0, position.getYSize()-1, getAvailableStyleSheet().getColor("windowdescent")); 116 output.drawLine(0, position.getXSize()-1, position.getYSize()-1, position.getYSize()-1, getAvailableStyleSheet().getColor("windowascent")); 117 output.drawLine(position.getXSize()-1, position.getXSize()-1, 0, position.getYSize()-1, getAvailableStyleSheet().getColor("windowascent")); 118 }else{ 119 /*output.drawRectangle(0, sizeX, 0, sizeY, getBrush(brushPressed)); 120 int x = getBrush(brushNormal).getX() / 2, y = getBrush(brushNormal).getY() / 2; 121 output.drawFilledRectangle(x, sizeX - 1 - x, y, sizeY - 1 - y, getBrush(brushNormal).readPixel(x, y));*/ 122 output.drawLine(0, position.getXSize()-1, 0, 0, getAvailableStyleSheet().getColor("windowascent")); 123 output.drawLine(0, 0, 0, position.getYSize()-1, getAvailableStyleSheet().getColor("windowascent")); 124 output.drawLine(0, position.getXSize()-1, position.getYSize()-1, position.getYSize()-1, getAvailableStyleSheet().getColor("windowdescent")); 125 output.drawLine(position.getXSize()-1, position.getXSize()-1, 0, position.getYSize()-1, getAvailableStyleSheet().getColor("windowdescent")); 126 } 127 128 output.drawText(sizeX/2, sizeY/2, text, getAvailableStyleSheet().getFontset("default")); 129 elementContainer.drawUpdate(this); 130 } 131 public override void onClick(int offsetX, int offsetY, int type = 0){ 132 if(type == 0){ 133 isPressed = !isPressed; 134 draw(); 135 invokeActionEvent(EventType.CLICK, isPressed); 136 isPressed = !isPressed; 137 draw(); 138 } 139 } 140 } 141 142 public class Label : WindowElement{ 143 public this(wstring text, string source, Coordinate coordinates){ 144 position = coordinates; 145 sizeX = coordinates.getXSize(); 146 sizeY = coordinates.getYSize(); 147 this.text = text; 148 this.source = source; 149 output = new BitmapDrawer(sizeX, sizeY); 150 //draw(); 151 } 152 public override void draw(){ 153 //writeln(elementContainer); 154 output.drawText(0, 0, text, getAvailableStyleSheet().getFontset("default"), 1); 155 elementContainer.drawUpdate(this); 156 } 157 public override void onClick(int offsetX, int offsetY, int type = 0){ 158 if(type == 0) 159 invokeActionEvent(EventType.CLICK, 0); 160 } 161 } 162 163 public class TextBox : WindowElement, TextInputListener{ 164 private bool enableEdit, insert; 165 private uint pos; 166 public int brush, textpos; 167 //public TextInputHandler tih; 168 169 public this(wstring text, string source, Coordinate coordinates){ 170 position = coordinates; 171 sizeX = coordinates.getXSize(); 172 sizeY = coordinates.getYSize(); 173 this.text = text; 174 this.source = source; 175 output = new BitmapDrawer(sizeX, sizeY); 176 inputHandler.addTextInputListener(source, this); 177 //insert = true; 178 //draw(); 179 } 180 181 public deprecated void addTextInputHandler(TextInputHandler t){ /** DEPRECATED. Will be removed soon in favor of static input handlers. */ 182 /*tih = t;*/ 183 inputHandler.addTextInputListener(source, this); 184 } 185 186 public void onClick(int offsetX, int offsetY, int type = 0){ 187 //writeln(0); 188 if(!enableEdit && type == 0){ 189 invokeActionEvent(EventType.READYFORTEXTINPUT, 0); 190 enableEdit = true; 191 inputHandler.startTextInput(source); 192 draw(); 193 } 194 } 195 public override void draw(){ 196 output.drawFilledRectangle(0, sizeX - 1, 0, sizeY - 1, getAvailableStyleSheet().getColor("window")); 197 output.drawRectangle(0, sizeX - 1, 0, sizeY - 1, getAvailableStyleSheet().getColor("windowascent")); 198 199 //draw cursor 200 if(enableEdit){ 201 int x = getAvailableStyleSheet().getFontset("default").letters['A'].getX() , y = getAvailableStyleSheet().getFontset("default").letters['A'].getY(); 202 if(!insert) 203 output.drawLine((x*pos) + 2, (x*pos) + 2, 2, 2 + y, getAvailableStyleSheet().getColor("selection")); 204 else 205 output.drawFilledRectangle((x*pos) + 2, (x*(pos + 1)) + 2, 2, 2 + y, getAvailableStyleSheet().getColor("selection")); 206 } 207 208 output.drawText(2, 2, text, getAvailableStyleSheet().getFontset("default"), 1); 209 elementContainer.drawUpdate(this); 210 } 211 212 alias onKey = WindowElement.onKey; 213 public void onKey(wchar c, int type){ 214 215 /*if(enableEdit){ 216 if(type == 0){ 217 text ~= c; 218 pos++; 219 draw(); 220 }else if(type == 1){ 221 pos++; 222 }else if(type == 2){ 223 pos--; 224 }else if(type == 3){ 225 invokeActionEvent(EventType.TEXTINPUT, 0, text); 226 }else{ 227 deleteCharacter(pos); 228 pos--; 229 draw(); 230 } 231 }*/ 232 } 233 private void deleteCharacter(int n){ 234 //text = remove(text, i); 235 wstring newtext; 236 for(int i; i < text.length; i++){ 237 if(i != n - 1){ 238 newtext ~= text[i]; 239 } 240 } 241 text = newtext; 242 } 243 public void focusGiven(){} 244 public void focusLost(){} 245 public void textInputEvent(uint timestamp, uint windowID, char[32] text){ 246 //writeln(0); 247 int j = pos; 248 wstring newtext; 249 for(int i ; i < pos ; i++){ 250 newtext ~= this.text[i]; 251 } 252 for(int i ; i < 32 ; i++){ 253 if(text[i] == 0){ 254 break; 255 } 256 else{ 257 newtext ~= text[i]; 258 pos++; 259 if(insert){ 260 j++; 261 } 262 } 263 } 264 for( ; j < this.text.length ; j++){ 265 newtext ~= this.text[j]; 266 } 267 this.text = newtext; 268 draw(); 269 } 270 271 public void dropTextInput(){ 272 enableEdit = false; 273 inputHandler.stopTextInput(source); 274 draw(); 275 invokeActionEvent(EventType.TEXTINPUT, 0, text); 276 } 277 278 279 public void textInputKeyEvent(uint timestamp, uint windowID, InputKey key){ 280 if(key == InputKey.ESCAPE || key == InputKey.ENTER){ 281 enableEdit = false; 282 inputHandler.stopTextInput(source); 283 draw(); 284 invokeActionEvent(EventType.TEXTINPUT, 0, text); 285 }else if(key == InputKey.BACKSPACE){ 286 if(pos > 0){ 287 deleteCharacter(pos); 288 pos--; 289 draw(); 290 } 291 /*if(pos > 0){ 292 if(pos == text.length){ 293 text.length--; 294 pos--; 295 296 } 297 }*/ 298 }else if(key == InputKey.DELETE){ 299 deleteCharacter(pos + 1); 300 draw(); 301 }else if(key == InputKey.CURSORLEFT){ 302 if(pos > 0){ 303 --pos; 304 draw(); 305 } 306 }else if(key == InputKey.CURSORRIGHT){ 307 if(pos < text.length){ 308 ++pos; 309 draw(); 310 } 311 }else if(key == InputKey.INSERT){ 312 insert = !insert; 313 draw(); 314 }else if(key == InputKey.HOME){ 315 pos = 0; 316 draw(); 317 }else if(key == InputKey.END){ 318 pos = text.length; 319 draw(); 320 } 321 } 322 } 323 324 325 public class ListBox : WindowElement, ActionListener, ElementContainer{ 326 public ListBoxColumn[] columns; 327 public int[] columnWidth; 328 public int brushHeader, brush, fontHeader, rowHeight; 329 public ushort selectionColor; 330 private bool fullRedraw, bodyDrawn; 331 private VSlider vSlider; 332 private HSlider hSlider; 333 private int fullX, hposition, vposition, selection, sliderX, sliderY, startY, endY; 334 private BitmapDrawer textArea, headerArea; 335 336 public this(string source, Coordinate coordinates, ListBoxColumn[] columns, int[] columnWidth, int rowHeight, /*VSlider vSlider = null, HSlider = null*/){ 337 position = coordinates; 338 sizeX = coordinates.getXSize(); 339 sizeY = coordinates.getYSize(); 340 //this.text = text; 341 this.source = source; 342 this.rowHeight = rowHeight; 343 this.columnWidth = columnWidth; 344 updateColumns(columns); 345 346 foreach(int i; columnWidth){ 347 fullX += i; 348 } 349 if(fullX < position.getXSize()){ 350 fullX = position.getXSize(); 351 } 352 353 output = new BitmapDrawer(sizeX, sizeY); 354 355 int foo = rowHeight * this.columns[0].elements.length; 356 if(foo < position.getYSize()) 357 foo = position.getXSize; 358 359 /*textArea = new BitmapDrawer(fullX, foo); 360 headerArea = new BitmapDrawer(fullX, rowHeight);*/ 361 //writeln(columns[0].elements.length,',', ((position.getYSize()-16-rowHeight) / rowHeight)); 362 /*this.vSlider = new VSlider(columns[0].elements.length - 1, ((position.getYSize()-17-rowHeight) / rowHeight), "vslider", Coordinate(position.getXSize - 16, 0, position.getXSize, position.getYSize() - 16)); 363 this.hSlider = new HSlider(fullX - 16, position.getXSize() - 16, "hslider", Coordinate(0, position.getYSize() - 16, position.getXSize() - 16, position.getYSize() )); 364 this.vSlider.al ~= this; 365 this.vSlider.elementContainer = this; 366 sliderX = vSlider.getX(); 367 368 369 this.hSlider.al ~= this; 370 this.hSlider.elementContainer = this; 371 sliderY = hSlider.getY();*/ 372 } 373 374 public void actionEvent(string source, int type, int value, wstring message){ 375 draw(); 376 } 377 public void actionEvent(string source, string subsource, int type, int value, wstring message){} 378 public void actionEvent(Event event){} 379 public void getFocus(WindowElement sender){} 380 public void dropFocus(WindowElement sender){} 381 public void drawUpdate(WindowElement sender){ 382 output.insertBitmap(sender.getPosition().left,sender.getPosition().top,sender.output.output); 383 384 if(!fullRedraw){ 385 /*output.insertBitmapSlice(0,0,headerArea.output,Coordinate(vposition,0,vposition + fullX - 1, rowHeight - 1)); 386 output.insertBitmapSlice(0, rowHeight, textArea.output, Coordinate(vposition,hposition * rowHeight,vposition + fullX - 1 , hposition * rowHeight + (sizeY - hSlider.getPosition().getYSize) - rowHeight));*/ 387 elementContainer.drawUpdate(this); 388 } 389 } 390 /*public Bitmap16Bit getStyleBrush(int style){ 391 return elementContainer.getStyleBrush(style); 392 }*/ 393 /*public Bitmap16Bit[wchar] getFontSet(int style){ 394 return elementContainer.getFontSet(style); 395 }*/ 396 public void updateColumns(ListBoxColumn[] lbc){ 397 columns = lbc; 398 fullX = 0; 399 selection = 0; 400 foreach(int i; columnWidth){ 401 fullX += i; 402 } 403 if(fullX < position.getXSize()){ 404 fullX = position.getXSize(); 405 } 406 int foo2 = rowHeight * this.columns[0].elements.length; 407 if(foo2 < position.getYSize()) 408 foo2 = position.getXSize; 409 410 textArea = new BitmapDrawer(fullX, foo2); 411 headerArea = new BitmapDrawer(fullX, rowHeight); 412 413 this.vSlider = new VSlider(columns[0].elements.length - 1, ((position.getYSize()-17-rowHeight) / rowHeight), "vslider", Coordinate(position.getXSize - 16, 0, position.getXSize, position.getYSize() - 16)); 414 this.hSlider = new HSlider(fullX - 16, position.getXSize() - 16, "hslider", Coordinate(0, position.getYSize() - 16, position.getXSize() - 16, position.getYSize() )); 415 this.vSlider.al ~= this; 416 this.vSlider.elementContainer = this; 417 sliderX = vSlider.getX(); 418 419 420 this.hSlider.al ~= this; 421 this.hSlider.elementContainer = this; 422 sliderY = hSlider.getY(); 423 bodyDrawn = false; 424 } 425 426 public StyleSheet getStyleSheet(){ 427 return getAvailableStyleSheet; 428 } 429 430 private void drawBody(){ 431 int foo; 432 for(int i; i < columns.length; i++){ 433 int bar; 434 for(int j; j < columns[i].elements.length; j++){ 435 //writeln(foo + 1, bar); 436 textArea.drawText(foo + 1, bar, columns[i].elements[j], getStyleSheet().getFontset("default"), 1); 437 438 bar += rowHeight; 439 } 440 foo += columnWidth[i]; 441 //writeln(foo, foo, 0, textArea.output.getX()-1); 442 textArea.drawLine(foo, foo, 0, textArea.output.getY()-2, getStyleSheet().getColor("windowascent")); 443 } 444 } 445 446 public override void draw(){ 447 fullRedraw = true; 448 449 450 451 452 int areaX, areaY; 453 454 vposition = vSlider.getSliderPosition(); 455 areaX = sizeX - vSlider.getPosition().getXSize; 456 457 458 hposition = hSlider.getSliderPosition(); 459 areaY = sizeY - hSlider.getPosition().getYSize; 460 461 //writeln(vposition, hposition); 462 463 464 output.drawFilledRectangle(0, position.getXSize(), 0, position.getYSize(),getStyleSheet().getColor("window")); 465 output.drawRectangle(0, position.getXSize() - 1, 0, position.getYSize() - 1,getStyleSheet().getColor("windowascent")); 466 467 468 // draw the header 469 output.drawLine(0, position.getXSize() - 1, rowHeight, rowHeight, getStyleSheet().getColor("windowascent")); 470 int foo; 471 for(int i; i < columnWidth.length; i++){ 472 headerArea.drawText(foo + 1, 0, columns[i].header, getStyleSheet().getFontset("default"), 1); 473 foo += columnWidth[i]; 474 headerArea.drawLine(foo, foo, 0, rowHeight - 2, getStyleSheet().getColor("windowascent")); 475 //writeln(foo); 476 } 477 478 output.insertBitmapSlice(0,0,headerArea.output,Coordinate(hposition,0,hposition + position.getXSize() - 17, rowHeight - 1)); 479 480 //draw the selector 481 if(selection - vposition >= 0 && vposition + ((position.getYSize()-17-rowHeight) / rowHeight) >= selection && columns[0].elements.length != 0) 482 output.drawFilledRectangle(1, position.getXSize() - 2, rowHeight + (rowHeight * (selection - vposition)), (rowHeight * 2) + (rowHeight * (selection - vposition)), getStyleSheet().getColor("selection")); 483 484 // draw the body 485 if(!bodyDrawn){ 486 bodyDrawn = true; 487 drawBody(); 488 } 489 490 //writeln(textArea.output.getX(),textArea.output.getY()); 491 output.insertBitmapSlice(0, rowHeight, textArea.output, Coordinate(hposition,vposition * rowHeight,hposition + position.getXSize() - 17 , vposition * rowHeight + areaY - rowHeight)); 492 493 vSlider.draw(); 494 hSlider.draw(); 495 496 elementContainer.drawUpdate(this); 497 fullRedraw = false; 498 //writeln(0); 499 } 500 public override void onClick(int offsetX, int offsetY, int type = 0){ 501 if(offsetX > (vSlider.getPosition().left) && offsetY > (vSlider.getPosition().top)){ 502 vSlider.onClick(offsetX - vSlider.getPosition().left, offsetY - vSlider.getPosition().top, type); 503 return; 504 505 }else if(offsetX > (hSlider.getPosition().left) && offsetY > (hSlider.getPosition().top)){ 506 //writeln(offsetX,',',offsetY); 507 hSlider.onClick(offsetX - hSlider.getPosition().left, offsetY - hSlider.getPosition().top, type); 508 return; 509 510 }else if(offsetY > rowHeight && type == 0){ 511 offsetY -= rowHeight; 512 //writeln(selection); 513 if(selection == (offsetY / rowHeight) + vposition){ 514 invokeActionEvent(EventType.TEXTBOXSELECT, (offsetY / rowHeight) + vposition); 515 } 516 else{ 517 if((offsetY / rowHeight) + vposition < columns[0].elements.length){ 518 selection = (offsetY / rowHeight) + vposition; 519 draw(); 520 } 521 } 522 } 523 } 524 public void onScroll(int x, int y, int wX, int wY){ 525 526 vSlider.onScroll(x,y,0,0); 527 hSlider.onScroll(x,y,0,0); 528 } 529 } 530 531 public class CheckBox : WindowElement{ 532 public int iconChecked, iconUnchecked; 533 private bool checked; 534 public int[] brush; 535 536 public this(wstring text, string source, Coordinate coordinates){ 537 position = coordinates; 538 sizeX = coordinates.getXSize(); 539 sizeY = coordinates.getYSize(); 540 this.text = text; 541 this.source = source; 542 brush ~= 2; 543 brush ~= 3; 544 output = new BitmapDrawer(sizeX, sizeY); 545 //draw(); 546 } 547 548 public override void draw(){ 549 output.drawText(0 , getAvailableStyleSheet().getImage("checkBoxA").getY, text, getAvailableStyleSheet().getFontset("default"), 1); 550 if(checked){ 551 output.insertBitmap(0, 0, getAvailableStyleSheet().getImage("checkBoxB")); 552 }else{ 553 output.insertBitmap(0, 0, getAvailableStyleSheet().getImage("checkBoxA")); 554 } 555 elementContainer.drawUpdate(this); 556 } 557 558 public override void onClick(int offsetX, int offsetY, int type = 0){ 559 checked = !checked; 560 draw(); 561 invokeActionEvent(EventType.CHECKBOX, checked); 562 } 563 } 564 565 public class RadioButtonGroup : WindowElement{ 566 public int iconChecked, iconUnchecked; 567 private int bposition, rowSpace, buttonpos; 568 public wstring[] options; 569 public int[] brush; 570 public ushort border, background; 571 572 public this(wstring text, string source, Coordinate coordinates, wstring[] options, int rowSpace, int buttonpos){ 573 this.position = coordinates; 574 sizeX = coordinates.getXSize(); 575 sizeY = coordinates.getYSize(); 576 this.text = text; 577 this.source = source; 578 this.options = options; 579 brush ~= 4; 580 brush ~= 5; 581 output = new BitmapDrawer(sizeX, sizeY); 582 //draw(); 583 } 584 585 public override void draw(){ 586 //output.drawFilledRectangle(0, sizeX-1, 0, sizeY-1, background); 587 output.drawRectangle(0, sizeX-1, 0, sizeY-1, getAvailableStyleSheet().getColor("windowascent")); 588 output.drawText(16,0,text, getAvailableStyleSheet().getFontset("default"),1); 589 for(int i; i < options.length; i++){ 590 591 output.drawText(16, 16 * (i+1),options[i],getAvailableStyleSheet().getFontset("default"),1); 592 if(bposition == i){ 593 output.insertBitmap(1, 16 * (i+1),getAvailableStyleSheet.getImage("radioButtonB")); 594 }else{ 595 output.insertBitmap(1, 16 * (i+1),getAvailableStyleSheet.getImage("radioButtonA")); 596 } 597 } 598 elementContainer.drawUpdate(this); 599 } 600 601 public override void onClick(int offsetX, int offsetY, int type = 0){ 602 bposition = (offsetY) / 16; 603 bposition--; 604 draw(); 605 invokeActionEvent(EventType.RADIOBUTTON, bposition); 606 } 607 public int getValue(){ 608 return bposition; 609 } 610 } 611 612 abstract class Slider : WindowElement{ 613 public int[] brush; 614 615 public int value, maxValue, barLength; 616 617 /* 618 * Returns the slider position. If barLenght > 1, then it returns the lower value. 619 */ 620 public int getSliderPosition(){ 621 return value; 622 } 623 } 624 625 public class VSlider : Slider{ 626 //public int[] brush; 627 628 //private int value, maxValue, barLength; 629 630 public this(int maxValue, int barLenght, string source, Coordinate coordinates){ 631 position = coordinates; 632 sizeX = coordinates.getXSize(); 633 sizeY = coordinates.getYSize(); 634 //this.text = text; 635 this.source = source; 636 this.maxValue = maxValue; 637 this.barLength = barLenght; 638 output = new BitmapDrawer(sizeX, sizeY); 639 brush ~= 6; 640 brush ~= 8; 641 //brush ~= 10; 642 //draw(); 643 } 644 public override void draw(){ 645 //draw background 646 //Bitmap16Bit sliderStyle = elementContainer.getStyleBrush(brush[2]); 647 //ushort backgroundColor = sliderStyle.readPixel(0,0), sliderColor = sliderStyle.readPixel(1,0); 648 output.drawFilledRectangle(0, sizeX , 0, sizeY , getAvailableStyleSheet.getColor("windowinactive")); 649 //draw upper arrow 650 output.insertBitmap(0,0,getAvailableStyleSheet.getImage("upArrowA")); 651 //draw lower arrow 652 output.insertBitmap(0, sizeY - getAvailableStyleSheet.getImage("downArrowA").getY(),getAvailableStyleSheet.getImage("downArrowA")); 653 //draw slider 654 if(maxValue > barLength){ 655 double sliderlength = position.getYSize() - (getAvailableStyleSheet.getImage("upArrowA")).getY()*2, unitlength = sliderlength/maxValue; 656 double sliderpos = unitlength * value, bl = unitlength * barLength; 657 int posA = to!int(sliderpos) + getAvailableStyleSheet.getImage("upArrowA").getY(), posB = to!int(bl + sliderpos) + getAvailableStyleSheet.getImage("upArrowA").getY(); 658 659 output.drawFilledRectangle(0,sizeX,posA, posB, getAvailableStyleSheet.getColor("windowascent")); 660 } 661 elementContainer.drawUpdate(this); 662 } 663 664 665 public override void onClick(int offsetX, int offsetY, int type = 0){ 666 if(offsetY <= getAvailableStyleSheet.getImage("upArrowA").getY()){ 667 if(value != 0) value--; 668 } 669 else if(sizeY-getAvailableStyleSheet.getImage("upArrowA").getY() <= offsetY){ 670 if(value < maxValue - barLength) value++; 671 } 672 else{ 673 offsetY -= getAvailableStyleSheet.getImage("upArrowA").getY(); 674 double sliderlength = position.getYSize() - (getAvailableStyleSheet.getImage("upArrowA").getY()*2), unitlength = sliderlength/maxValue; 675 int v = to!int(offsetY / unitlength); 676 //value = ((sizeY - (elementContainer.getStyleBrush(brush[1]).getY() * 2)) - offsetY) * (value / maxValue); 677 if(v < maxValue - barLength) value = v; 678 else value = maxValue - barLength; 679 } 680 invokeActionEvent(EventType.SLIDER, value); 681 draw(); 682 683 } 684 public override void onScroll(int x, int y, int wX, int wY){ 685 686 if(x == 1){ 687 if(value != 0) value--; 688 }else if(x == -1){ 689 if(value < maxValue - barLength) value++; 690 } 691 invokeActionEvent(EventType.SLIDER, value); 692 draw(); 693 } 694 } 695 696 public class HSlider : Slider{ 697 public this(int maxValue, int barLenght, string source, Coordinate coordinates){ 698 position = coordinates; 699 sizeX = coordinates.getXSize(); 700 sizeY = coordinates.getYSize(); 701 //this.text = text; 702 this.source = source; 703 this.maxValue = maxValue; 704 this.barLength = barLenght; 705 //writeln(barLenght,',',maxValue); 706 output = new BitmapDrawer(sizeX, sizeY); 707 brush ~= 14; 708 brush ~= 16; 709 //brush ~= 10; 710 //draw(); 711 } 712 public override void draw(){ 713 //draw background 714 //Bitmap16Bit sliderStyle = elementContainer.getStyleBrush(brush[2]); 715 //ushort backgroundColor = sliderStyle.readPixel(0,0), sliderColor = sliderStyle.readPixel(1,0); 716 output.drawFilledRectangle(0, sizeX , 0, sizeY , getAvailableStyleSheet().getColor("windowinactive")); 717 //draw left arrow 718 output.insertBitmap(0,0,getAvailableStyleSheet.getImage("leftArrowA")); 719 //draw right arrow 720 output.insertBitmap(sizeX - getAvailableStyleSheet.getImage("rightArrowA").getX(),0,getAvailableStyleSheet.getImage("rightArrowA")); 721 //draw slider 722 if(maxValue > barLength){ 723 double sliderlength = position.getXSize() - (getAvailableStyleSheet.getImage("rightArrowA").getX()*2), unitlength = sliderlength/maxValue; 724 double sliderpos = unitlength * value, bl = unitlength * barLength; 725 726 int posA = to!int(sliderpos) + getAvailableStyleSheet.getImage("rightArrowA").getY(), posB = to!int(bl + sliderpos) + getAvailableStyleSheet.getImage("rightArrowA").getY(); 727 728 output.drawFilledRectangle(posA, posB, 0, position.getYSize(),getAvailableStyleSheet().getColor("windowascent")); 729 } 730 elementContainer.drawUpdate(this); 731 } 732 public override void onClick(int offsetX, int offsetY, int type = 0){ 733 if(offsetX <= getAvailableStyleSheet.getImage("rightArrowA").getX()){ 734 if(value != 0) value--; 735 } 736 else if(sizeX-getAvailableStyleSheet.getImage("rightArrowA").getX() <= offsetX){ 737 if(value < maxValue - barLength) value++; 738 } 739 else{ 740 offsetX -= getAvailableStyleSheet.getImage("rightArrowA").getX(); 741 double sliderlength = position.getXSize() - (elementContainer.getStyleSheet.getImage("rightArrowA").getX()*2), unitlength = sliderlength/maxValue; 742 int v = to!int(offsetX / unitlength); 743 if(v < maxValue - barLength) value = v; 744 else value = maxValue - barLength; 745 } 746 invokeActionEvent(EventType.SLIDER, value); 747 draw(); 748 749 } 750 public override void onScroll(int x, int y, int wX, int wY){ 751 if(y == -1){ 752 if(value != 0) value--; 753 }else if(y == 1){ 754 if(value < maxValue - barLength) value++; 755 } 756 invokeActionEvent(EventType.SLIDER, value); 757 draw(); 758 } 759 } 760 761 /** 762 * To create drop-down lists, menu bars, etc. 763 */ 764 public class PopUpMenu: PopUpElement{ 765 private wstring[] texts; 766 private string[] sources; 767 private string subsource; 768 private uint[int] hotkeyCodes; 769 private Bitmap16Bit[int] icons; 770 public BitmapDrawer output; 771 private ElementContainer elementContainer; 772 public static InputHandler inputhandler; 773 774 public this(int columnheight, string subsource, string[] sources, wstring[] texts, uint[int] hotkeyCodes = null){ 775 776 } 777 778 /** 779 * Use this if you want icons in your list. 780 * All the icons have to be the same exact size, otherwise it might cause exceptions. 781 */ 782 public this(int columnheight, string subsource, string[] sources, wstring[] texts, Bitmap16Bit[int] icons, uint[int] hotkeyCodes = null){ 783 784 } 785 786 public void onClick(int x, int y){ 787 788 } 789 public void onKey(uint keycode){ 790 791 } 792 public void onScroll(int x, int y, int wX, int wY){ 793 794 } 795 public void addPopUpHandler(PopUpHandler p){} 796 } 797 public interface PopUpElement{ 798 public void onClick(int x, int y); 799 public void addPopUpHandler(PopUpHandler p); 800 } 801 public interface PopUpHandler{ 802 public void addPopUpElement(PopUpElement p); 803 } 804 805 /*public interface IElement{ 806 public void onClick(); 807 public Coordinate getPosition(); 808 }*/ 809 /** 810 * For use with ListBoxes and similar types 811 */ 812 public struct ListBoxColumn{ 813 public wstring header; 814 public wstring[] elements; 815 816 this(wstring header, wstring[] elements){ 817 this.header = header; 818 this.elements = elements; 819 } 820 821 /*this(string header, string[] elements){ 822 this.header = to!wstring(header); 823 //this.elements = elements; 824 }*/ 825 826 public void removeByNumber(int i){ 827 elements = remove(elements, i); 828 } 829 } 830 831 public class Event{ 832 public string source, subsource, path, filename; 833 public wstring text; 834 public int value, type; 835 /** 836 *If a field is unneeded, leave it blank by setting it to null. 837 */ 838 this(string source, string subsource, string path, string filename, wstring textinput, int value, int type){ 839 this.source = source; 840 this.subsource = subsource; 841 this.path = path; 842 this.filename = filename; 843 this.text = textinput; 844 this.value = value; 845 this.type = type; 846 } 847 } 848 849 public interface ActionListener{ 850 //public void actionEvent(string source, int type, int value, wstring message); 851 //public void actionEvent(string source, string subSource, int type, int value, wstring message); 852 /// During development, I decided to move to a more "Swing-like" event system, use this instead. Better for adding new features in the future. 853 public void actionEvent(Event event); 854 } 855 856 public interface ElementContainer{ 857 public StyleSheet getStyleSheet(); 858 //public Bitmap16Bit[wchar] getFontSet(int style); 859 public void drawUpdate(WindowElement sender); 860 public void getFocus(WindowElement sender); 861 public void dropFocus(WindowElement sender); 862 } 863 864 public interface Focusable{ 865 public void focusGiven(); 866 public void focusLost(); 867 } 868 869 public enum EventType{ 870 READYFORTEXTINPUT =-1, 871 CLICK = 0, 872 TEXTINPUT = 1, 873 SLIDER = 2, 874 TEXTBOXSELECT = 3, 875 CHECKBOX = 4, 876 RADIOBUTTON = 5, 877 FILEDIALOGEVENT = 6 878 }