TDE graphics utilities
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.

410 lines
13KB

  1. /***************************************************************************
  2. paletteviewscrolledarea.cpp
  3. -------------------
  4. begin : Sun Jul 17 2000
  5. copyright : (C) 2000 by Artur Rataj
  6. email : art@zeus.polsl.gliwice.pl
  7. ***************************************************************************/
  8. /***************************************************************************
  9. * *
  10. * This program is free software; you can redistribute it and/or modify *
  11. * it under the terms of the GNU General Public License as published by *
  12. * the Free Software Foundation; either version 2 of the License, or *
  13. * (at your option) any later version. *
  14. * *
  15. ***************************************************************************/
  16. #include <stdlib.h>
  17. #include <tqptrlist.h>
  18. #include <tqcolor.h>
  19. #include <tqcursor.h>
  20. #include <tqbrush.h>
  21. #include <tqpainter.h>
  22. #include <tqpixmap.h>
  23. #include <tqpen.h>
  24. #include <tqfontmetrics.h>
  25. #include <tqtimer.h>
  26. #include <kglobal.h>
  27. #include <kcolordrag.h>
  28. #include <tqscrollbar.h>
  29. #include "palette.h"
  30. #include "palettehistory.h"
  31. #include "kcoloreditdoc.h"
  32. #include "kcoloreditview.h"
  33. #include "paletteviewscrolledarea.h"
  34. #include "paletteviewscrolledarea.moc"
  35. PaletteViewScrolledArea::PaletteViewScrolledArea(const int defaultCellWidth,
  36. const int defaultCellHeight, const int cellSpacing, TQScrollBar* scrollBar,
  37. TQScrollBar* hScrollBar, KColorEditView* view, TQWidget* parent, const char* name)
  38. : TQFrame(parent, name) {
  39. this->defaultCellWidth = defaultCellWidth;
  40. this->defaultCellHeight = defaultCellHeight;
  41. this->cellSpacing = cellSpacing;
  42. this->scrollBar = scrollBar;
  43. this->hScrollBar = hScrollBar;
  44. this->view = view;
  45. setBackgroundMode(NoBackground);
  46. scrollTimeoutTimer = new TQTimer(this);
  47. connect(scrollTimeoutTimer, TQT_SIGNAL( timeout() ), TQT_SLOT( slotScrollTimeout() ));
  48. scrollTimeout = true;
  49. mousePressed = false;
  50. cursorPositioning = false;
  51. colorChosen = false;
  52. setCellsSizes();
  53. slotCursorFollowsChosenColor(false);
  54. this->scrollBar->setValue(0);
  55. slotViewColorNames(false);
  56. setMinimumSize(1, 1);
  57. }
  58. PaletteViewScrolledArea::~PaletteViewScrolledArea() {
  59. }
  60. void PaletteViewScrolledArea::slotCursorFollowsChosenColor(bool follows) {
  61. cursorFollowsChosenColor = follows;
  62. }
  63. void PaletteViewScrolledArea::slotViewColorNames(bool viewColorNames) {
  64. this->viewColorNames = viewColorNames;
  65. }
  66. void PaletteViewScrolledArea::redraw() {
  67. //setCellsSizes();
  68. repaintPalette();
  69. }
  70. void PaletteViewScrolledArea::repaintPalette() {
  71. repaint(false);
  72. }
  73. void PaletteViewScrolledArea::checkSelectionAutoScroll(const int mousePosY) {
  74. if(mousePosY < 0)
  75. scrollPalette(-8, 50);
  76. else if(mousePosY > height() - 1)
  77. scrollPalette(8, 50);
  78. }
  79. void PaletteViewScrolledArea::scrollPalette(const int amount, const int timeout) {
  80. if(scrollTimeout) {
  81. scrollBy(amount);
  82. scrollTimeout = false;
  83. scrollTimeoutTimer->start(timeout, true);
  84. }
  85. }
  86. void PaletteViewScrolledArea::slotScrollTimeout() {
  87. scrollTimeout = true;
  88. if(mousePressed) {
  89. TQPoint cursorPoint = mapFromGlobal(TQCursor::pos());
  90. setCursorPos(cursorPoint.x(), cursorPoint.y());
  91. selectionEnd = cursorPos();
  92. if(selectionEnd >= selectionBegin)
  93. setSelection(selectionBegin, selectionEnd);
  94. else
  95. setSelection(selectionEnd, selectionBegin);
  96. checkSelectionAutoScroll(cursorPoint.y());
  97. repaintPalette();
  98. }
  99. }
  100. void PaletteViewScrolledArea::setCursorPos(const int pos) {
  101. int oldCursorPos = document()->paletteCursorPos();
  102. document()->setPaletteCursorPos(pos);
  103. if(pos != oldCursorPos)
  104. view->slotCursorPosChanged(pos);
  105. }
  106. bool PaletteViewScrolledArea::setCursorPos(const int x, const int y) {
  107. int shiftedY = y + scrollBar->value();
  108. int shiftedX = x + hScrollBar->value();
  109. int cursorColumn = (shiftedX + rowWidth/cellsInRow/2)*cellsInRow/rowWidth;
  110. int cursorRow;
  111. if(shiftedY >= 0)
  112. cursorRow = (shiftedY + cellSpacing)/rowHeight;
  113. else
  114. cursorRow = -1;
  115. bool atCursorLocation = abs(cursorColumn*rowWidth/cellsInRow - shiftedX) < cellSpacing + 1;
  116. if(!atCursorLocation) {
  117. atCursorLocation = abs(cursorRow*rowHeight - shiftedY) < cellSpacing + 1;
  118. if(atCursorLocation)
  119. cursorColumn = 0;
  120. }
  121. if(atCursorLocation || cursorPositioning) {
  122. if(cursorColumn > cellsInRow - 1) {
  123. cursorColumn = 0;
  124. ++cursorRow;
  125. }
  126. int tmpCursorPos = cursorRow*cellsInRow + cursorColumn;
  127. if(tmpCursorPos < 0)
  128. tmpCursorPos = 0;
  129. else if(tmpCursorPos >= palette()->length()) {
  130. if(tmpCursorPos == palette()->length() &&
  131. cursorColumn == 0 &&
  132. selectionMin() == selectionMax())
  133. /* if cursor has been set after the last color and the color is
  134. * also the last in a row, and there is no selection, scroll the
  135. * palette to ensure the cursor is visible
  136. */
  137. scrollBy(rowHeight*2);
  138. if(tmpCursorPos > palette()->length())
  139. tmpCursorPos = palette()->length();
  140. }
  141. setCursorPos(tmpCursorPos);
  142. }
  143. return atCursorLocation;
  144. }
  145. void PaletteViewScrolledArea::setSelection(const int min, const int max) {
  146. document()->setPaletteSelection(min, max);
  147. }
  148. void PaletteViewScrolledArea::setCellsSizes() {
  149. rowWidth = width();
  150. cellWidth = defaultCellWidth;
  151. cellHeight = defaultCellHeight;
  152. if(viewColorNames) {
  153. TQPainter painter;
  154. painter.begin(this);
  155. if(cellHeight < painter.fontMetrics().height()) {
  156. int prevCellHeight = cellHeight;
  157. cellHeight = painter.fontMetrics().height();
  158. cellWidth = cellHeight*cellWidth/prevCellHeight;
  159. }
  160. painter.end();
  161. }
  162. if(viewColorNames)
  163. cellsInRow = 1;
  164. else
  165. cellsInRow = rowWidth/(cellWidth + cellSpacing*2);
  166. if(viewColorNames)
  167. rowHeight = cellHeight + cellSpacing*2;
  168. else
  169. rowHeight = (int)(rowWidth*1.0/cellsInRow/
  170. ( cellWidth + cellSpacing*2 )*( cellHeight + cellSpacing*2 ) + 0.5);
  171. cellHeight = rowHeight - cellSpacing*2;
  172. rowsNum = (palette()->length() + cellsInRow - 1)/cellsInRow;
  173. cellTableHeight = rowsNum*rowHeight;
  174. int contentsHeight;
  175. if(palette()->length() != 0 &&
  176. ( palette()->length()%cellsInRow ) == 0)
  177. contentsHeight = cellTableHeight + rowHeight;
  178. else
  179. contentsHeight = cellTableHeight;
  180. int scrollBarRange = contentsHeight - 1 - height();
  181. if(scrollBarRange < 0)
  182. scrollBarRange = 0;
  183. scrollBar->setRange(0, scrollBarRange);
  184. scrollBar->setSteps(rowHeight, height());
  185. }
  186. Palette* PaletteViewScrolledArea::palette() const {
  187. return document()->paletteHistory()->editableStream();
  188. }
  189. int PaletteViewScrolledArea::cursorPos() const {
  190. return document()->paletteCursorPos();
  191. }
  192. int PaletteViewScrolledArea::selectionMin() const{
  193. return document()->paletteSelectionBegin();
  194. }
  195. int PaletteViewScrolledArea::selectionMax() const {
  196. return document()->paletteSelectionEnd();
  197. }
  198. void PaletteViewScrolledArea::paintEvent(TQPaintEvent* /*event*/) {
  199. setCellsSizes();
  200. TQPixmap pixmap(size());
  201. TQPainter painter;
  202. painter.begin(TQT_TQPAINTDEVICE(&pixmap), this);
  203. TQFontMetrics fontMetrics = painter.fontMetrics();
  204. int maxLineWidth;
  205. if(viewColorNames) {
  206. int maxTextLength = 0;
  207. for(int index = 0; index < palette()->length(); ++index) {
  208. int currTextLength = fontMetrics.width(
  209. palette()->color(index)->name());
  210. if(currTextLength > maxTextLength)
  211. maxTextLength = currTextLength;
  212. }
  213. maxLineWidth = cellWidth + cellSpacing*2 +
  214. cellSpacing*3 + maxTextLength + 1;
  215. } else
  216. maxLineWidth = rowWidth;
  217. int width = rowWidth;
  218. if(maxLineWidth > width) {
  219. hScrollBar->setRange(0, maxLineWidth - width);
  220. hScrollBar->setSteps(8, width);
  221. hScrollBar->show();
  222. } else {
  223. hScrollBar->setValue(0);
  224. hScrollBar->hide();
  225. }
  226. int posY = scrollBar->value();
  227. int firstRow = posY/rowHeight;
  228. int lastRow = (posY + height() - 1 + rowHeight - 1)/rowHeight;
  229. if(viewColorNames)
  230. painter.fillRect(0, 0, rowWidth, height(),
  231. TQBrush( TQFrame::palette().active().base() ));
  232. TQBrush normalBackgroundBrush(TQFrame::palette().active().background());
  233. TQBrush selectedBackgroundBrush(TQFrame::palette().active().highlight());
  234. TQBrush foregroundBrush;
  235. TQBrush cursorBrush(TQFrame::palette().active().foreground());
  236. TQPen backgroundPen(TQFrame::palette().active().foreground());
  237. int min = selectionMin();
  238. int max = selectionMax();
  239. int fontAscent = fontMetrics.ascent();
  240. int xBegin = -hScrollBar->value();
  241. for(int x = 0; x < cellsInRow; ++x) {
  242. int xEnd = -hScrollBar->value();
  243. if(viewColorNames)
  244. xEnd += cellWidth + cellSpacing*2;
  245. else
  246. xEnd += (x + 1)*(width - 1)/cellsInRow;
  247. int cellWithSpacingWidth = xEnd - xBegin + 1;
  248. int cellWidth = cellWithSpacingWidth - 2*cellSpacing;
  249. for(int y = firstRow; y <= lastRow; ++y) {
  250. int yBegin = y*rowHeight - posY;
  251. int currCellNum = y*cellsInRow + x;
  252. TQBrush* backgroundBrush;
  253. if(currCellNum >= min && currCellNum < max)
  254. backgroundBrush = &selectedBackgroundBrush;
  255. else
  256. backgroundBrush = &normalBackgroundBrush;
  257. if(currCellNum < palette()->length()) {
  258. Color* color = palette()->color(currCellNum);
  259. TQBrush foregroundBrush(TQColor(
  260. color->component(Color::RED_INDEX),
  261. color->component(Color::GREEN_INDEX),
  262. color->component(Color::BLUE_INDEX) ));
  263. painter.fillRect(xBegin, yBegin, cellWithSpacingWidth, cellSpacing,
  264. *backgroundBrush);
  265. painter.fillRect(xBegin, yBegin + rowHeight - cellSpacing, cellWithSpacingWidth, cellSpacing,
  266. *backgroundBrush);
  267. TQBrush* backgroundOrCursorBrush;
  268. if(cursorPos() == currCellNum)
  269. backgroundOrCursorBrush = &cursorBrush;
  270. else
  271. backgroundOrCursorBrush = backgroundBrush;
  272. painter.fillRect(xBegin, yBegin + cellSpacing, cellSpacing, cellHeight,
  273. *backgroundOrCursorBrush);
  274. painter.fillRect(xBegin + cellWithSpacingWidth - cellSpacing, yBegin + cellSpacing,
  275. cellSpacing, cellHeight,
  276. *backgroundBrush);
  277. painter.fillRect(xBegin + cellSpacing, yBegin + cellSpacing, cellWidth, cellHeight,
  278. foregroundBrush);
  279. if(viewColorNames) {
  280. painter.setPen(backgroundPen);
  281. painter.drawText(xBegin + cellWithSpacingWidth + cellSpacing*3,
  282. yBegin + rowHeight/2 + fontAscent/2, color->name());
  283. }
  284. } else {
  285. if(cursorPos() == currCellNum) {
  286. painter.fillRect(xBegin, yBegin + cellSpacing, cellSpacing, cellHeight,
  287. cursorBrush);
  288. painter.fillRect(xBegin, yBegin, cellSpacing, cellSpacing,
  289. *backgroundBrush);
  290. painter.fillRect(xBegin, yBegin + rowHeight - cellSpacing, cellSpacing, cellSpacing,
  291. *backgroundBrush);
  292. painter.fillRect(xBegin + cellSpacing, yBegin, cellWithSpacingWidth - cellSpacing, rowHeight,
  293. *backgroundBrush);
  294. } else
  295. painter.fillRect(xBegin, yBegin, cellWithSpacingWidth, rowHeight,
  296. *backgroundBrush);
  297. }
  298. }
  299. xBegin = xEnd + 1;
  300. }
  301. painter.end();
  302. painter.begin(this);
  303. painter.drawPixmap(0, 0, pixmap);
  304. painter.end();
  305. }
  306. int PaletteViewScrolledArea::colorIndex(const TQPoint& point) const {
  307. int colorColumn = point.x()*cellsInRow/rowWidth;
  308. int colorRow = (point.y() + scrollBar->value())/rowHeight;
  309. int colorIndex = colorRow*cellsInRow + colorColumn;
  310. if(colorIndex > palette()->length() - 1 ||
  311. colorIndex < 0)
  312. colorIndex = -1;
  313. return colorIndex;
  314. }
  315. TQColor PaletteViewScrolledArea::color(const TQPoint& point) const {
  316. Color* color = palette()->color(colorIndex( point ));
  317. return TQColor(color->component( Color::RED_INDEX ),
  318. color->component( Color::GREEN_INDEX ),
  319. color->component( Color::BLUE_INDEX ));
  320. }
  321. void PaletteViewScrolledArea::mousePressEvent(TQMouseEvent* event) {
  322. cursorPositioning = false;
  323. if(( cursorPositioning = setCursorPos(event->x(), event->y()) )) {
  324. selectionBegin = cursorPos();
  325. setSelection(selectionBegin, selectionBegin);
  326. redraw();
  327. colorChosen = false;
  328. } else {
  329. colorDragPoint = event->pos();
  330. colorChosen = true;
  331. }
  332. mousePressed = true;
  333. }
  334. void PaletteViewScrolledArea::mouseMoveEvent(TQMouseEvent* event) {
  335. if(cursorPositioning) {
  336. setCursorPos(event->x(), event->y());
  337. selectionEnd = cursorPos();
  338. if(selectionEnd >= selectionBegin)
  339. setSelection(selectionBegin, selectionEnd);
  340. else
  341. setSelection(selectionEnd, selectionBegin);
  342. checkSelectionAutoScroll(event->y());
  343. redraw();
  344. } else {
  345. /* check if it is a color drag */
  346. if(colorIndex( colorDragPoint ) != -1) {
  347. if(abs( event->x() - colorDragPoint.x() ) > 2 ||
  348. abs( event->y() - colorDragPoint.y() ) > 2) {
  349. TQColor draggedColor = color(colorDragPoint);
  350. KColorDrag* colorDrag = KColorDrag::makeDrag(draggedColor, this);
  351. colorDrag->dragCopy();
  352. } else
  353. colorChosen = true;
  354. }
  355. }
  356. }
  357. void PaletteViewScrolledArea::mouseReleaseEvent(TQMouseEvent* /*event*/) {
  358. if(colorChosen) {
  359. if(colorIndex( colorDragPoint ) != -1) {
  360. int index = colorIndex(colorDragPoint);
  361. chooseColor(palette()->color( index ));
  362. if(cursorFollowsChosenColor) {
  363. setCursorPos(index);
  364. setSelection(cursorPos(), cursorPos());
  365. redraw();
  366. }
  367. }
  368. colorChosen = false;
  369. }
  370. mousePressed = false;
  371. }
  372. void PaletteViewScrolledArea::chooseColor(Color* const color) {
  373. view->chooseColor(color);
  374. }
  375. KColorEditDoc* PaletteViewScrolledArea::document() const {
  376. return view->document();
  377. }
  378. void PaletteViewScrolledArea::scrollBy(const int y) {
  379. scrollBar->setValue(scrollBar->value() + y);
  380. }