You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

191 lines
6.2KB

  1. /**
  2. *
  3. * Copyright (c) 2015 Pascal Gauthier.
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software Foundation,
  17. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  18. *
  19. */
  20. #include "ProgramListBox.h"
  21. #include "PluginData.h"
  22. #include "DXLookNFeel.h"
  23. #include "Dexed.h"
  24. ProgramListBox::ProgramListBox(const String name, int numCols) : Component(name) {
  25. cols = numCols;
  26. rows = 32 / numCols;
  27. selectedPgm = -1;
  28. hasContent = false;
  29. dragCandidate = -1;
  30. readOnly = false;
  31. programNames.clear();
  32. }
  33. void ProgramListBox::paint(Graphics &g) {
  34. int pgm = 0;
  35. g.setColour(Colour(20,18,18));
  36. g.fillRect(0,0,getWidth(), getHeight());
  37. g.setColour(Colour(0,0,0));
  38. g.drawLine(0,0,getWidth(), 0, 2);
  39. g.setColour(Colour(3,3,1));
  40. g.drawLine(0,0,0,getHeight(),2);
  41. g.setColour(Colour(34,32,32));
  42. g.drawLine(getWidth(), 3, getWidth(), getHeight(), 2);
  43. g.setColour(Colour(75,73,73));
  44. g.drawLine(0,getHeight(),getWidth(),getHeight(), 2);
  45. const float dashLength[] = { 4, 4 };
  46. g.setColour(Colour(83,76,69));
  47. for(int i=1;i<cols;i++) {
  48. Line<float> line(cellWidth*i,0,cellWidth*i,getHeight());
  49. g.drawDashedLine(line, dashLength, 2);
  50. }
  51. for(int i=1;i<rows;i++) {
  52. Line<float> line(2, cellHeight*i,getWidth(),cellHeight*i);
  53. g.drawDashedLine(line, dashLength, 2);
  54. }
  55. for(int i=0;i<cols;i++) {
  56. for(int j=0;j<rows;j++) {
  57. if ( selectedPgm == pgm && dragCandidate == -1 ) {
  58. g.setColour(DXLookNFeel::fillColour);
  59. g.fillRoundedRectangle(cellWidth*i+2, cellHeight*j + 2, cellWidth - 4, cellHeight - 4, 0);
  60. }
  61. if ( hasContent == true ) {
  62. if ( dragCandidate != pgm ) {
  63. g.setColour(Colours::white);
  64. g.drawFittedText(programNames[pgm], cellWidth * i , cellHeight * j, cellWidth, cellHeight, Justification::centred, true);
  65. } else {
  66. g.setColour(DXLookNFeel::fillColour);
  67. g.fillRoundedRectangle(cellWidth*i+2, cellHeight*j + 2, cellWidth - 4, cellHeight - 4, 0);
  68. }
  69. }
  70. pgm++;
  71. }
  72. }
  73. }
  74. void ProgramListBox::resized() {
  75. cellWidth = getWidth() / cols;
  76. cellHeight = getHeight() / rows;
  77. }
  78. void ProgramListBox::setCartridge(Cartridge &cart) {
  79. cartContent = cart;
  80. cartContent.getProgramNames(programNames);
  81. hasContent = true;
  82. repaint();
  83. }
  84. void ProgramListBox::addListener(ProgramListBoxListener *listener) {
  85. this->listener = listener;
  86. }
  87. int ProgramListBox::programPosition(int x, int y) {
  88. return (y / cellHeight) + ((x / cellWidth) * rows);
  89. }
  90. void ProgramListBox::mouseDown(const MouseEvent &event) {
  91. if ( ! hasContent )
  92. return;
  93. int pos = programPosition(event.getMouseDownX(), event.getMouseDownY());
  94. if ( event.mods.isRightButtonDown() || event.mods.isAnyModifierKeyDown() ) {
  95. listener->programRightClicked(this, pos);
  96. return;
  97. }
  98. listener->programSelected(this, pos);
  99. }
  100. void ProgramListBox::mouseUp(const MouseEvent &event) {
  101. }
  102. void ProgramListBox::mouseDrag(const MouseEvent &event) {
  103. if ( ! hasContent )
  104. return;
  105. if ( dragCandidate != -1 )
  106. return;
  107. if ( event.getDistanceFromDragStart() < 7 )
  108. return;
  109. if (DragAndDropContainer* const dragContainer = DragAndDropContainer::findParentDragContainerFor(this)) {
  110. Image snapshot (Image::ARGB, cellWidth, cellHeight, true);
  111. int position = programPosition(event.getMouseDownX(), event.getMouseDownY());
  112. Graphics g(snapshot);
  113. g.setColour(DXLookNFeel::lightBackground);
  114. g.fillRect(0,0,cellWidth, cellHeight);
  115. g.setColour(Colours::white);
  116. g.drawFittedText(programNames[position], 0, 0, cellWidth, cellHeight, Justification::centred, true);
  117. void *src = cartContent.getRawVoice() + (position*128);
  118. var description = var(src, 128);
  119. dragContainer->startDragging(description, this, snapshot, false);
  120. }
  121. }
  122. void ProgramListBox::setSelected(int idx) {
  123. selectedPgm = idx;
  124. }
  125. Cartridge &ProgramListBox::getCurrentCart() {
  126. return cartContent;
  127. }
  128. bool ProgramListBox::isInterestedInDragSource (const SourceDetails& dragSourceDetail) {
  129. if ( readOnly )
  130. return false;
  131. if ( ! hasContent )
  132. return false;
  133. Component *comp = dragSourceDetail.sourceComponent.get();
  134. if ( comp == nullptr )
  135. return false;
  136. if ( dynamic_cast<ProgramListBox*>(comp) == nullptr )
  137. return false;
  138. return true;
  139. }
  140. void ProgramListBox::itemDropped(const SourceDetails& dragSourceDetails) {
  141. dragCandidate = programPosition(dragSourceDetails.localPosition.x, dragSourceDetails.localPosition.y);
  142. MemoryBlock* block = dragSourceDetails.description.getBinaryData();
  143. if ( listener != nullptr )
  144. listener->programDragged(this, dragCandidate, (char *)block->getData());
  145. dragCandidate = -1;
  146. repaint();
  147. }
  148. void ProgramListBox::itemDragEnter(const SourceDetails &dragSourceDetails) {
  149. dragCandidate = programPosition(dragSourceDetails.localPosition.x, dragSourceDetails.localPosition.y);
  150. repaint();
  151. }
  152. void ProgramListBox::itemDragMove(const SourceDetails &dragSourceDetails) {
  153. dragCandidate = programPosition(dragSourceDetails.localPosition.x, dragSourceDetails.localPosition.y);
  154. repaint();
  155. }
  156. void ProgramListBox::itemDragExit(const SourceDetails &dragSourceDetails) {
  157. dragCandidate = -1;
  158. repaint();
  159. }