#include "fullscreen.h" #include #include #include #include #include #include #include #include #include #include #include #include KIFFullScreenHandle::KIFFullScreenHandle(QWidget *parent, const char *name) : QButton(parent, name) { setToggleButton(true); setOn(true); } QSize KIFFullScreenHandle::sizeHint() const { return(QSize(12, 12)); } void KIFFullScreenHandle::drawButton(QPainter *p) { p->fillRect(0, 0, width(), height(), colorGroup().background()); qDrawShadePanel(p, 0, 0, width(), height(), colorGroup(), isDown()); qDrawArrow(p, isOn() || isDown() ? Qt::LeftArrow : Qt::RightArrow, Qt::WindowsStyle, isDown(), 2, 2, width()-4, height()-4, colorGroup(), true); } KIFFullScreen::KIFFullScreen(KIFImage *image, bool maxpect, QWidget *parent, const char *name, bool dirBtnEnabled) : QWidget(parent, name, WType_Popup) { KConfig *config = KGlobal::config(); config->setGroup("UISettings"); setFocusPolicy(StrongFocus); setBackgroundMode(NoBackground); gc = XCreateGC(x11Display(), RootWindow(x11Display(), x11Screen()), 0, 0); // alloc color for lowcolor displays c = config->readColorEntry("FullScreenColor", &Qt::white); XSetForeground(x11Display(), gc, c.pixel()); imageBuffer = image; max = maxpect; connect(imageBuffer, SIGNAL(updated()), this, SLOT(slotUpdateFromImage())); connect(imageBuffer, SIGNAL(invalidFile()), this, SLOT(slotInvalidFile())); move(0, 0); resize(QApplication::desktop()->size()); QGridLayout *layout = new QGridLayout(this); handle = new KIFFullScreenHandle(this); connect(handle, SIGNAL(toggled(bool)), this, SLOT(slotHandleToggled(bool))); layout->addWidget(handle, 0, 0); if(dirBtnEnabled){ prevImageBtn = new QToolButton(this); QToolTip::add(prevImageBtn, i18n("Previous image in folder")); prevImageBtn->setIconSet(BarIcon("backimage", 16)); connect(prevImageBtn, SIGNAL(clicked()), this, SLOT(slotPrevImageClicked())); layout->addWidget(prevImageBtn, 0, 1); nextImageBtn = new QToolButton(this); QToolTip::add(nextImageBtn, i18n("Next image in folder")); nextImageBtn->setIconSet(BarIcon("forwardimage", 16)); connect(nextImageBtn, SIGNAL(clicked()), this, SLOT(slotNextImageClicked())); layout->addWidget(nextImageBtn, 0, 2); } else{ prevImageBtn = nextImageBtn = NULL; } prevListBtn = new QToolButton(this); QToolTip::add(prevListBtn, i18n("Previous image in file list")); prevListBtn->setIconSet(BarIcon("1leftarrow", 16)); connect(prevListBtn, SIGNAL(clicked()), this, SLOT(slotPrevListClicked())); layout->addWidget(prevListBtn, 0, 3); nextListBtn = new QToolButton(this); QToolTip::add(nextListBtn, i18n("Next image in file list")); nextListBtn->setIconSet(BarIcon("1rightarrow", 16)); connect(nextListBtn, SIGNAL(clicked()), this, SLOT(slotNextListClicked())); layout->addWidget(nextListBtn, 0, 4); handle->setMinimumHeight(prevListBtn->sizeHint().height()); incBrightnessBtn = new QToolButton(this); QToolTip::add(incBrightnessBtn, i18n("Increase brightness")); incBrightnessBtn->setIconSet(BarIcon("brightness", 16)); connect(incBrightnessBtn, SIGNAL(clicked()), this, SLOT(slotIncBrightnessClicked())); layout->addWidget(incBrightnessBtn, 0, 5); decBrightnessBtn = new QToolButton(this); QToolTip::add(decBrightnessBtn, i18n("Decrease brightness")); decBrightnessBtn->setIconSet(BarIcon("dim", 16)); connect(decBrightnessBtn, SIGNAL(clicked()), this, SLOT(slotDecBrightnessClicked())); layout->addWidget(decBrightnessBtn, 0, 6); incContrastBtn = new QToolButton(this); QToolTip::add(incContrastBtn, i18n("Increase contrast")); incContrastBtn->setIconSet(BarIcon("contrast+", 16)); connect(incContrastBtn, SIGNAL(clicked()), this, SLOT(slotIncContrastClicked())); layout->addWidget(incContrastBtn, 0, 7); decContrastBtn = new QToolButton(this); QToolTip::add(decContrastBtn, i18n("Decrease contrast")); decContrastBtn->setIconSet(BarIcon("contrast-", 16)); connect(decContrastBtn, SIGNAL(clicked()), this, SLOT(slotDecContrastClicked())); layout->addWidget(decContrastBtn, 0, 8); rotateBtn = new QToolButton(this); QToolTip::add(rotateBtn, i18n("Rotate")); rotateBtn->setIconSet(BarIcon("rotate", 16)); connect(rotateBtn, SIGNAL(clicked()), this, SLOT(slotRotateClicked())); layout->addWidget(rotateBtn, 0, 9); zoomBtn = new QToolButton(this); QToolTip::add(zoomBtn, i18n("Zoom in/out")); zoomBtn->setIconSet(BarIcon("viewmag", 16)); connect(zoomBtn, SIGNAL(clicked()), this, SLOT(slotZoomClicked())); layout->addWidget(zoomBtn, 0, 10); layout->setColStretch(11, 1); layout->setRowStretch(1, 1); if(!config->readBoolEntry("ViewerToolbar", true)) handle->toggle(); maxBtnClicked = false; } KIFFullScreen::~KIFFullScreen() { XFreeGC(x11Display(), gc); } void KIFFullScreen::setColor(const QColor &color) { c = color; XSetForeground(x11Display(), gc, c.pixel()); } void KIFFullScreen::slotHandleToggled(bool on) { if(on){ if(prevImageBtn){ prevImageBtn->show(); nextImageBtn->show(); } prevListBtn->show(); nextListBtn->show(); incBrightnessBtn->show(); decBrightnessBtn->show(); incContrastBtn->show(); decContrastBtn->show(); rotateBtn->show(); zoomBtn->show(); } else{ if(prevImageBtn){ prevImageBtn->hide(); nextImageBtn->hide(); } prevListBtn->hide(); nextListBtn->hide(); incBrightnessBtn->hide(); decBrightnessBtn->hide(); incContrastBtn->hide(); decContrastBtn->hide(); rotateBtn->hide(); zoomBtn->hide(); } KConfig *config = KGlobal::config(); config->setGroup("UISettings"); config->writeEntry("ViewerToolbar", on); config->sync(); update(); } void KIFFullScreen::slotIncContrastClicked() { QApplication::setOverrideCursor(WaitCursor); QImage tmpImage = pix.convertToImage(); KImageEffect::contrastHSV(tmpImage, true); pix.convertFromImage(tmpImage); repaint(false); QApplication::restoreOverrideCursor(); } void KIFFullScreen::slotDecContrastClicked() { QApplication::setOverrideCursor(WaitCursor); QImage tmpImage = pix.convertToImage(); KImageEffect::contrastHSV(tmpImage, false); pix.convertFromImage(tmpImage); repaint(false); QApplication::restoreOverrideCursor(); } void KIFFullScreen::slotIncBrightnessClicked() { int i, count, h, s, v; unsigned int *data; QColor pixel; QApplication::setOverrideCursor(WaitCursor); QImage tmpImage = pix.convertToImage(); if(tmpImage.depth() < 32) tmpImage = tmpImage.convertDepth(32); count = tmpImage.width()*tmpImage.height(); data = (unsigned int *)tmpImage.bits(); for(i=0; i < count; ++i){ pixel.setRgb(qRed(data[i]), qGreen(data[i]), qBlue(data[i])); pixel.hsv(&h, &s, &v); if(v+10 <= 255) v+=10; else v = 255; pixel.setHsv(h, s, v); data[i] = qRgb(pixel.red(), pixel.green(), pixel.blue()); } pix.convertFromImage(tmpImage); repaint(false); QApplication::restoreOverrideCursor(); } void KIFFullScreen::slotDecBrightnessClicked() { int i, count, h, s, v; unsigned int *data; QColor pixel; QApplication::setOverrideCursor(WaitCursor); QImage tmpImage = pix.convertToImage(); if(tmpImage.depth() < 32) tmpImage = tmpImage.convertDepth(32); count = tmpImage.width()*tmpImage.height(); data = (unsigned int *)tmpImage.bits(); for(i=0; i < count; ++i){ pixel.setRgb(qRed(data[i]), qGreen(data[i]), qBlue(data[i])); pixel.hsv(&h, &s, &v); if(v-10 > 0) v-=10; else v = 0; pixel.setHsv(h, s, v); data[i] = qRgb(pixel.red(), pixel.green(), pixel.blue()); } pix.convertFromImage(tmpImage); repaint(false); QApplication::restoreOverrideCursor(); } void KIFFullScreen::slotRotateClicked() { QApplication::setOverrideCursor(WaitCursor); QImage tmpImage = pix.convertToImage(); tmpImage = KImageEffect::rotate(tmpImage, KImageEffect::Rotate90); scale(tmpImage); pix.convertFromImage(tmpImage); repaint(false); QApplication::restoreOverrideCursor(); } void KIFFullScreen::slotZoomClicked() { QApplication::setOverrideCursor(WaitCursor); if(pix.width() == width() || pix.height() == height()){ if(pix.width() > width() || pix.height() > height()){ QImage tmpImage = pix.convertToImage(); int w = tmpImage.width(); int h = tmpImage.height(); if(w > width()){ float percent = ((float)width())/w; w = (int)(w*percent); h = (int)(h*percent); } if(h > height()){ float percent = ((float)height())/h; w = (int)(w*percent); h = (int)(h*percent); } tmpImage = tmpImage.smoothScale(w, h); pix.convertFromImage(tmpImage); } else pix.convertFromImage(*imageBuffer->image()); } else{ QImage tmpImage(*imageBuffer->image()); int w = tmpImage.width(); int h = tmpImage.height(); float percentW, percentH; percentW = percentH = 0.0; if(tmpImage.width() < width()) percentW = ((float)width())/w; if(tmpImage.height() < height()) percentH = ((float)height())/h; if(percentW && ((int)(h * percentW)) <= height()){ w = (int)(w*percentW); h = (int)(h*percentW); } else if(percentH && ((int)(w * percentH)) <= width()){ w = (int)(w*percentH); h = (int)(h*percentH); } tmpImage = tmpImage.smoothScale(w, h); pix.convertFromImage(tmpImage); } repaint(false); QApplication::restoreOverrideCursor(); } void KIFFullScreen::slotUpdateFromImage() { if(imageBuffer->image()->width() > width() || imageBuffer->image()->height() > height()){ QImage tmpImage(*imageBuffer->image()); scale(tmpImage); pix.convertFromImage(tmpImage); } else if(max && imageBuffer->image()->width() < width() && imageBuffer->image()->height() < height()){ QImage tmpImage(*imageBuffer->image()); scale(tmpImage); pix.convertFromImage(tmpImage); } else pix.convertFromImage(*imageBuffer->image()); repaint(false); } void KIFFullScreen::slotInvalidFile() { ; } void KIFFullScreen::scale(QImage &tmpImage) { if(tmpImage.width() > width() || tmpImage.height() > height()){ int w = tmpImage.width(); int h = tmpImage.height(); if(w > width()){ float percent = ((float)width())/w; w = (int)(w*percent); h = (int)(h*percent); } if(h > height()){ float percent = ((float)height())/h; w = (int)(w*percent); h = (int)(h*percent); } tmpImage = tmpImage.smoothScale(w, h); } else if(max && tmpImage.width() < width() && tmpImage.height() < height()){ int w = tmpImage.width(); int h = tmpImage.height(); float percentW, percentH; // decide if to scale horizontally or vertically percentW = percentH = 0.0; if(tmpImage.width() < width()) percentW = ((float)width())/w; if(tmpImage.height() < height()) percentH = ((float)height())/h; // can we scale width to screensize w/out making height offscreen if(percentW && ((int)(h * percentW)) <= height()){ w = (int)(w*percentW); h = (int)(h*percentW); } // if not try to scale horizontally w/out making width offscreen else if(percentH && ((int)(w * percentH)) <= width()){ w = (int)(w*percentH); h = (int)(h*percentH); } tmpImage = tmpImage.smoothScale(w, h); } } void KIFFullScreen::paintEvent(QPaintEvent *ev) { if(pix.isNull()){ XFillRectangle(x11Display(), winId(), gc, 0, 0, width(), height()); return; } QRect pixRect(0, 0, pix.width(), pix.height()); QRect drawRect(ev->rect()); if(pix.width() < width()){ pixRect.setLeft(((width()-pix.width())/2)-1); pixRect.setWidth(pix.width()); // need to reset } if(pix.height() < height()){ pixRect.setTop(((height()-pix.height())/2)-1); pixRect.setHeight(pix.height()); } pixRect = pixRect.intersect(drawRect); if(pix.mask()) XFillRectangle(x11Display(), winId(), gc, pixRect.x(), pixRect.y(), drawRect.width(), drawRect.height()); bitBlt(this, pixRect.topLeft(), &pix, drawRect, Qt::CopyROP); // fill in the edges int rects = 0; XRectangle rectangles[4]; if(drawRect.top() < pixRect.top()){ rectangles[rects].x = drawRect.x(); rectangles[rects].y = drawRect.x(); rectangles[rects].width = drawRect.width(); rectangles[rects].height = pixRect.top()-drawRect.top(); ++rects; } if(drawRect.left() < pixRect.left()){ rectangles[rects].x = drawRect.x(); rectangles[rects].y = pixRect.top()-drawRect.top(); rectangles[rects].width = pixRect.left()-drawRect.left(); rectangles[rects].height = drawRect.height()-pixRect.top(); ++rects; } if(drawRect.right() > pixRect.right()){ rectangles[rects].x = pixRect.right()+1; rectangles[rects].y = pixRect.top()-drawRect.top(); rectangles[rects].width = drawRect.right()-pixRect.right(); rectangles[rects].height = drawRect.height()-pixRect.top(); ++rects; } if(drawRect.bottom() > pixRect.bottom()){ rectangles[rects].x = pixRect.left(); rectangles[rects].y = pixRect.bottom()+1; rectangles[rects].width = pixRect.width(); rectangles[rects].height = drawRect.bottom()-pixRect.bottom(); ++rects; } if(rects) XFillRectangles(x11Display(), winId(), gc, rectangles, rects); } void KIFFullScreen::closeEvent(QCloseEvent *ev) { pix.resize(0, 0); ev->accept(); emit finished(); } void KIFFullScreen::mousePressEvent(QMouseEvent *ev) { if(ev->button() == LeftButton){ close(); } } void KIFFullScreen::slotNextListClicked() { emit(nextList()); } void KIFFullScreen::slotPrevListClicked() { emit(prevList()); } void KIFFullScreen::slotNextImageClicked() { emit(nextImage()); } void KIFFullScreen::slotPrevImageClicked() { emit(prevImage()); } void KIFFullScreen::keyPressEvent(QKeyEvent *ev) { int key = ev->key(); if(key == Key_Left) emit(prevList()); else if(key == Key_Right || key == Key_Space) emit(nextList()); else if(key == Key_Up) emit(prevImage()); else if(key == Key_Down) emit(nextImage()); else if(key == Key_Escape || key == Key_Enter || key == Key_Return) close(); }