/*************************************************************************** paletteviewscrolledarea.cpp ------------------- begin : Sun Jul 17 2000 copyright : (C) 2000 by Artur Rataj email : art@zeus.polsl.gliwice.pl ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "palette.h" #include "palettehistory.h" #include "kcoloreditdoc.h" #include "kcoloreditview.h" #include "paletteviewscrolledarea.h" #include "paletteviewscrolledarea.moc" PaletteViewScrolledArea::PaletteViewScrolledArea(const int defaultCellWidth, const int defaultCellHeight, const int cellSpacing, TQScrollBar* scrollBar, TQScrollBar* hScrollBar, KColorEditView* view, TQWidget* parent, const char* name) : TQFrame(parent, name) { this->defaultCellWidth = defaultCellWidth; this->defaultCellHeight = defaultCellHeight; this->cellSpacing = cellSpacing; this->scrollBar = scrollBar; this->hScrollBar = hScrollBar; this->view = view; setBackgroundMode(NoBackground); scrollTimeoutTimer = new TQTimer(this); connect(scrollTimeoutTimer, TQT_SIGNAL( timeout() ), TQT_SLOT( slotScrollTimeout() )); scrollTimeout = true; mousePressed = false; cursorPositioning = false; colorChosen = false; setCellsSizes(); slotCursorFollowsChosenColor(false); this->scrollBar->setValue(0); slotViewColorNames(false); setMinimumSize(1, 1); } PaletteViewScrolledArea::~PaletteViewScrolledArea() { } void PaletteViewScrolledArea::slotCursorFollowsChosenColor(bool follows) { cursorFollowsChosenColor = follows; } void PaletteViewScrolledArea::slotViewColorNames(bool viewColorNames) { this->viewColorNames = viewColorNames; } void PaletteViewScrolledArea::redraw() { //setCellsSizes(); repaintPalette(); } void PaletteViewScrolledArea::repaintPalette() { repaint(false); } void PaletteViewScrolledArea::checkSelectionAutoScroll(const int mousePosY) { if(mousePosY < 0) scrollPalette(-8, 50); else if(mousePosY > height() - 1) scrollPalette(8, 50); } void PaletteViewScrolledArea::scrollPalette(const int amount, const int timeout) { if(scrollTimeout) { scrollBy(amount); scrollTimeout = false; scrollTimeoutTimer->start(timeout, true); } } void PaletteViewScrolledArea::slotScrollTimeout() { scrollTimeout = true; if(mousePressed) { TQPoint cursorPoint = mapFromGlobal(TQCursor::pos()); setCursorPos(cursorPoint.x(), cursorPoint.y()); selectionEnd = cursorPos(); if(selectionEnd >= selectionBegin) setSelection(selectionBegin, selectionEnd); else setSelection(selectionEnd, selectionBegin); checkSelectionAutoScroll(cursorPoint.y()); repaintPalette(); } } void PaletteViewScrolledArea::setCursorPos(const int pos) { int oldCursorPos = document()->paletteCursorPos(); document()->setPaletteCursorPos(pos); if(pos != oldCursorPos) view->slotCursorPosChanged(pos); } bool PaletteViewScrolledArea::setCursorPos(const int x, const int y) { int shiftedY = y + scrollBar->value(); int shiftedX = x + hScrollBar->value(); int cursorColumn = (shiftedX + rowWidth/cellsInRow/2)*cellsInRow/rowWidth; int cursorRow; if(shiftedY >= 0) cursorRow = (shiftedY + cellSpacing)/rowHeight; else cursorRow = -1; bool atCursorLocation = abs(cursorColumn*rowWidth/cellsInRow - shiftedX) < cellSpacing + 1; if(!atCursorLocation) { atCursorLocation = abs(cursorRow*rowHeight - shiftedY) < cellSpacing + 1; if(atCursorLocation) cursorColumn = 0; } if(atCursorLocation || cursorPositioning) { if(cursorColumn > cellsInRow - 1) { cursorColumn = 0; ++cursorRow; } int tmpCursorPos = cursorRow*cellsInRow + cursorColumn; if(tmpCursorPos < 0) tmpCursorPos = 0; else if(tmpCursorPos >= palette()->length()) { if(tmpCursorPos == palette()->length() && cursorColumn == 0 && selectionMin() == selectionMax()) /* if cursor has been set after the last color and the color is * also the last in a row, and there is no selection, scroll the * palette to ensure the cursor is visible */ scrollBy(rowHeight*2); if(tmpCursorPos > palette()->length()) tmpCursorPos = palette()->length(); } setCursorPos(tmpCursorPos); } return atCursorLocation; } void PaletteViewScrolledArea::setSelection(const int min, const int max) { document()->setPaletteSelection(min, max); } void PaletteViewScrolledArea::setCellsSizes() { rowWidth = width(); cellWidth = defaultCellWidth; cellHeight = defaultCellHeight; if(viewColorNames) { TQPainter painter; painter.begin(this); if(cellHeight < painter.fontMetrics().height()) { int prevCellHeight = cellHeight; cellHeight = painter.fontMetrics().height(); cellWidth = cellHeight*cellWidth/prevCellHeight; } painter.end(); } if(viewColorNames) cellsInRow = 1; else cellsInRow = rowWidth/(cellWidth + cellSpacing*2); if(viewColorNames) rowHeight = cellHeight + cellSpacing*2; else rowHeight = (int)(rowWidth*1.0/cellsInRow/ ( cellWidth + cellSpacing*2 )*( cellHeight + cellSpacing*2 ) + 0.5); cellHeight = rowHeight - cellSpacing*2; rowsNum = (palette()->length() + cellsInRow - 1)/cellsInRow; cellTableHeight = rowsNum*rowHeight; int contentsHeight; if(palette()->length() != 0 && ( palette()->length()%cellsInRow ) == 0) contentsHeight = cellTableHeight + rowHeight; else contentsHeight = cellTableHeight; int scrollBarRange = contentsHeight - 1 - height(); if(scrollBarRange < 0) scrollBarRange = 0; scrollBar->setRange(0, scrollBarRange); scrollBar->setSteps(rowHeight, height()); } Palette* PaletteViewScrolledArea::palette() const { return document()->paletteHistory()->editableStream(); } int PaletteViewScrolledArea::cursorPos() const { return document()->paletteCursorPos(); } int PaletteViewScrolledArea::selectionMin() const{ return document()->paletteSelectionBegin(); } int PaletteViewScrolledArea::selectionMax() const { return document()->paletteSelectionEnd(); } void PaletteViewScrolledArea::paintEvent(TQPaintEvent* /*event*/) { setCellsSizes(); TQPixmap pixmap(size()); TQPainter painter; painter.begin(TQT_TQPAINTDEVICE(&pixmap), this); TQFontMetrics fontMetrics = painter.fontMetrics(); int maxLineWidth; if(viewColorNames) { int maxTextLength = 0; for(int index = 0; index < palette()->length(); ++index) { int currTextLength = fontMetrics.width( palette()->color(index)->name()); if(currTextLength > maxTextLength) maxTextLength = currTextLength; } maxLineWidth = cellWidth + cellSpacing*2 + cellSpacing*3 + maxTextLength + 1; } else maxLineWidth = rowWidth; int width = rowWidth; if(maxLineWidth > width) { hScrollBar->setRange(0, maxLineWidth - width); hScrollBar->setSteps(8, width); hScrollBar->show(); } else { hScrollBar->setValue(0); hScrollBar->hide(); } int posY = scrollBar->value(); int firstRow = posY/rowHeight; int lastRow = (posY + height() - 1 + rowHeight - 1)/rowHeight; if(viewColorNames) painter.fillRect(0, 0, rowWidth, height(), TQBrush( TQFrame::palette().active().base() )); TQBrush normalBackgroundBrush(TQFrame::palette().active().background()); TQBrush selectedBackgroundBrush(TQFrame::palette().active().highlight()); TQBrush foregroundBrush; TQBrush cursorBrush(TQFrame::palette().active().foreground()); TQPen backgroundPen(TQFrame::palette().active().foreground()); int min = selectionMin(); int max = selectionMax(); int fontAscent = fontMetrics.ascent(); int xBegin = -hScrollBar->value(); for(int x = 0; x < cellsInRow; ++x) { int xEnd = -hScrollBar->value(); if(viewColorNames) xEnd += cellWidth + cellSpacing*2; else xEnd += (x + 1)*(width - 1)/cellsInRow; int cellWithSpacingWidth = xEnd - xBegin + 1; int cellWidth = cellWithSpacingWidth - 2*cellSpacing; for(int y = firstRow; y <= lastRow; ++y) { int yBegin = y*rowHeight - posY; int currCellNum = y*cellsInRow + x; TQBrush* backgroundBrush; if(currCellNum >= min && currCellNum < max) backgroundBrush = &selectedBackgroundBrush; else backgroundBrush = &normalBackgroundBrush; if(currCellNum < palette()->length()) { Color* color = palette()->color(currCellNum); TQBrush foregroundBrush(TQColor( color->component(Color::RED_INDEX), color->component(Color::GREEN_INDEX), color->component(Color::BLUE_INDEX) )); painter.fillRect(xBegin, yBegin, cellWithSpacingWidth, cellSpacing, *backgroundBrush); painter.fillRect(xBegin, yBegin + rowHeight - cellSpacing, cellWithSpacingWidth, cellSpacing, *backgroundBrush); TQBrush* backgroundOrCursorBrush; if(cursorPos() == currCellNum) backgroundOrCursorBrush = &cursorBrush; else backgroundOrCursorBrush = backgroundBrush; painter.fillRect(xBegin, yBegin + cellSpacing, cellSpacing, cellHeight, *backgroundOrCursorBrush); painter.fillRect(xBegin + cellWithSpacingWidth - cellSpacing, yBegin + cellSpacing, cellSpacing, cellHeight, *backgroundBrush); painter.fillRect(xBegin + cellSpacing, yBegin + cellSpacing, cellWidth, cellHeight, foregroundBrush); if(viewColorNames) { painter.setPen(backgroundPen); painter.drawText(xBegin + cellWithSpacingWidth + cellSpacing*3, yBegin + rowHeight/2 + fontAscent/2, color->name()); } } else { if(cursorPos() == currCellNum) { painter.fillRect(xBegin, yBegin + cellSpacing, cellSpacing, cellHeight, cursorBrush); painter.fillRect(xBegin, yBegin, cellSpacing, cellSpacing, *backgroundBrush); painter.fillRect(xBegin, yBegin + rowHeight - cellSpacing, cellSpacing, cellSpacing, *backgroundBrush); painter.fillRect(xBegin + cellSpacing, yBegin, cellWithSpacingWidth - cellSpacing, rowHeight, *backgroundBrush); } else painter.fillRect(xBegin, yBegin, cellWithSpacingWidth, rowHeight, *backgroundBrush); } } xBegin = xEnd + 1; } painter.end(); painter.begin(this); painter.drawPixmap(0, 0, pixmap); painter.end(); } int PaletteViewScrolledArea::colorIndex(const TQPoint& point) const { int colorColumn = point.x()*cellsInRow/rowWidth; int colorRow = (point.y() + scrollBar->value())/rowHeight; int colorIndex = colorRow*cellsInRow + colorColumn; if(colorIndex > palette()->length() - 1 || colorIndex < 0) colorIndex = -1; return colorIndex; } TQColor PaletteViewScrolledArea::color(const TQPoint& point) const { Color* color = palette()->color(colorIndex( point )); return TQColor(color->component( Color::RED_INDEX ), color->component( Color::GREEN_INDEX ), color->component( Color::BLUE_INDEX )); } void PaletteViewScrolledArea::mousePressEvent(TQMouseEvent* event) { cursorPositioning = false; if(( cursorPositioning = setCursorPos(event->x(), event->y()) )) { selectionBegin = cursorPos(); setSelection(selectionBegin, selectionBegin); redraw(); colorChosen = false; } else { colorDragPoint = event->pos(); colorChosen = true; } mousePressed = true; } void PaletteViewScrolledArea::mouseMoveEvent(TQMouseEvent* event) { if(cursorPositioning) { setCursorPos(event->x(), event->y()); selectionEnd = cursorPos(); if(selectionEnd >= selectionBegin) setSelection(selectionBegin, selectionEnd); else setSelection(selectionEnd, selectionBegin); checkSelectionAutoScroll(event->y()); redraw(); } else { /* check if it is a color drag */ if(colorIndex( colorDragPoint ) != -1) { if(abs( event->x() - colorDragPoint.x() ) > 2 || abs( event->y() - colorDragPoint.y() ) > 2) { TQColor draggedColor = color(colorDragPoint); KColorDrag* colorDrag = KColorDrag::makeDrag(draggedColor, this); colorDrag->dragCopy(); } else colorChosen = true; } } } void PaletteViewScrolledArea::mouseReleaseEvent(TQMouseEvent* /*event*/) { if(colorChosen) { if(colorIndex( colorDragPoint ) != -1) { int index = colorIndex(colorDragPoint); chooseColor(palette()->color( index )); if(cursorFollowsChosenColor) { setCursorPos(index); setSelection(cursorPos(), cursorPos()); redraw(); } } colorChosen = false; } mousePressed = false; } void PaletteViewScrolledArea::chooseColor(Color* const color) { view->chooseColor(color); } KColorEditDoc* PaletteViewScrolledArea::document() const { return view->document(); } void PaletteViewScrolledArea::scrollBy(const int y) { scrollBar->setValue(scrollBar->value() + y); }