Re: Thumbnail Bar
Aurélien Gâteau <[email protected]> Fri, 21 Mar 2008 23:14:32 +0100
| Newsgroups | gmane.comp.kde.gwenview |
|---|---|
| Message-ID | <[email protected]> |
Hello Ilya, Great work! Attached is my "interpretation" of your work. Ilya Konkov a écrit : > Hello. > > New patch. Summary: > 1. Delegate now uses stylesheet style to paint background/border. Good idea. The design you produced is beautiful! I think at least some of it should go to the browse thumbnail view. For example the white border around the images. > 2. There is no speedbar and save button code. If you want, I can add > save button back. I don't think we need them, so it's ok. > 3. Stylesheet is generated in ThumbnailBarView using system colors. +1 > 4. OxygenStyle draws QListView's borders around viewport, not around > whole widget like other styles that I've tried do: > http://img523.imageshack.us/img523/7441/oxygendiffgu4.png > Left is Oxygen. > So to ensure common look I used QWindowsStyle. However drop and > context menus don't look native because of that =( I saw your workaround for this. Not exactly elegant, but I couldn't come up with something better :( > 5. Thumnail bar was moved to part container in document view, so it > doesn't cover image. I am not sure about the code that adds the bar to > partContainer's layout, it looks ugly. Hum... I changed this code quite a bit, mostly by having two instances of ThumbnailBar: one for fullscreen mode and one for view mode (more on this later). I achieved a bit different layout: http://bayimg.com/kaJkOAaBd > Also don't know how to add actions (toggle and probably shrink/enlarge > thumbnails) from main window to mDocument's status bar. Should be easier in the attached version, since the view mode ThumbnailBar is handled by the DocumentView class. > I think directories should be hidden in thumbnail bar. How to filter > them out using an existing proxy model class? > If you want to keep dirs, I should probably add text to delegate. I agree, directories shouldn't appear here. But it's going to be a bit complicated because it will require the use of a different model than the browse-mode thumbnail view. As I said, I introduced two instances of ThumbnailBar. It avoids tricky layouting code and makes it possible to use smaller thumbnails in fullscreen mode. While I find the design you produced beautiful, I think we need two different designs for the two modes: - In view mode, the bar looks a bit inconsistent with the rest of the more "standard" widgets. The background color should be closer to the image background and it should uses a standard scroll bar (OT: that zooming status bar should probably go, it looks weird with the thumbnail bar, and I find myself not liking it that much) - In fullscreen mode the thumbnail bar should look darker, in order to match the rest of the fullscreen bar. Maybe there should be less padding around the thumbnails too, to avoid taking too much vertical space. Nevertheless, great work! Aurélien PS: You should set your own name in the copyright headers of files you create, unless you want to give up your rights on these files to me. ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ _______________________________________________ Gwenview-general mailing list Gwenview-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org https://lists.sourceforge.net/lists/listinfo/gwenview-general
thumbnailbar2.diff
(text/x-diff, 23 KB)
diff --git a/gwenview/app/CMakeLists.txt b/gwenview/app/CMakeLists.txt
index 9d9fca1..dc08aa6 100644
--- a/gwenview/app/CMakeLists.txt
+++ b/gwenview/app/CMakeLists.txt
@@ -24,6 +24,7 @@ set(gwenview_SRCS
savebar.cpp
sidebar.cpp
thumbnailviewhelper.cpp
+ thumbnailbarview.cpp
)
if (Nepomuk_FOUND)
diff --git a/gwenview/app/documentview.cpp b/gwenview/app/documentview.cpp
index f7a4b89..11f5e98 100644
--- a/gwenview/app/documentview.cpp
+++ b/gwenview/app/documentview.cpp
@@ -32,6 +32,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <kstatusbar.h>
// Local
+#include "thumbnailbarview.h"
#include <lib/imageview.h>
#include <lib/imageviewpart.h>
#include <lib/mimetypeutils.h>
@@ -54,6 +55,7 @@ struct DocumentViewPrivate {
QWidget* mPartContainer;
QVBoxLayout* mPartContainerLayout;
KStatusBar* mStatusBar;
+ ThumbnailBarView* mThumbnailBar;
bool mStatusBarVisible;
KParts::ReadOnlyPart* mPart;
@@ -91,8 +93,14 @@ DocumentView::DocumentView(QWidget* parent)
d->mStatusBar = new KStatusBar(d->mPartContainer);
d->mStatusBar->hide();
+ d->mThumbnailBar = new ThumbnailBarView(d->mPartContainer);
+ ThumbnailBarItemDelegate* delegate = new ThumbnailBarItemDelegate(d->mThumbnailBar);
+ d->mThumbnailBar->setItemDelegate(delegate);
+ d->mThumbnailBar->hide();
+
d->mPartContainerLayout = new QVBoxLayout(d->mPartContainer);
d->mPartContainerLayout->addWidget(d->mStatusBar);
+ d->mPartContainerLayout->addWidget(d->mThumbnailBar);
d->mPartContainerLayout->setMargin(0);
d->mPartContainerLayout->setSpacing(0);
}
@@ -108,6 +116,11 @@ KStatusBar* DocumentView::statusBar() const {
}
+ThumbnailBarView* DocumentView::thumbnailBar() const {
+ return d->mThumbnailBar;
+}
+
+
void DocumentView::setStatusBarVisible(bool visible) {
d->mStatusBarVisible = visible;
d->mStatusBar->setVisible(visible);
diff --git a/gwenview/app/documentview.h b/gwenview/app/documentview.h
index e3b09fe..6f0cef4 100644
--- a/gwenview/app/documentview.h
+++ b/gwenview/app/documentview.h
@@ -32,6 +32,7 @@ namespace Gwenview {
class DocumentViewPrivate;
class ImageViewPart;
+class ThumbnailBarView;
/**
* Holds the active document view, or show a message if there is no active
@@ -43,6 +44,8 @@ public:
DocumentView(QWidget* parent);
~DocumentView();
+ ThumbnailBarView* thumbnailBar() const;
+
/**
* Reset the view
*/
diff --git a/gwenview/app/mainwindow.cpp b/gwenview/app/mainwindow.cpp
index e4f08d1..0906239 100644
--- a/gwenview/app/mainwindow.cpp
+++ b/gwenview/app/mainwindow.cpp
@@ -71,6 +71,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#endif
#include "savebar.h"
#include "sidebar.h"
+#include "thumbnailbarview.h"
#include "thumbnailviewhelper.h"
#include <lib/archiveutils.h>
#include <lib/document/documentfactory.h>
@@ -125,6 +126,7 @@ struct MainWindowState {
QAction* mActiveViewModeAction;
bool mSideBarVisible;
Qt::WindowStates mWindowState;
+ bool mThumbnailBarVisible;
};
struct MainWindow::Private {
@@ -158,6 +160,7 @@ struct MainWindow::Private {
QAction* mToggleSlideShowAction;
KToggleAction* mShowMenuBarAction;
KToggleAction* mShowFilterBar;
+ KToggleAction* mToggleThumbnailBarAction;
SortedDirModel* mDirModel;
ContextManager* mContextManager;
@@ -183,15 +186,7 @@ struct MainWindow::Private {
layout->setSpacing(0);
setupThumbnailView(mCentralSplitter);
- mDocumentView = new DocumentView(mCentralSplitter);
- connect(mDocumentView, SIGNAL(completed()),
- mWindow, SLOT(slotPartCompleted()) );
- connect(mDocumentView, SIGNAL(partChanged(KParts::Part*)),
- mWindow, SLOT(createGUI(KParts::Part*)) );
- connect(mDocumentView, SIGNAL(previousImageRequested()),
- mWindow, SLOT(goToPrevious()) );
- connect(mDocumentView, SIGNAL(nextImageRequested()),
- mWindow, SLOT(goToNext()) );
+ setupDocumentView(mCentralSplitter);
mSideBarContainer = new QStackedWidget(mCentralSplitter);
mSideBar = new SideBar(mSideBarContainer);
@@ -268,6 +263,23 @@ struct MainWindow::Private {
layout->addWidget(statusBar);
}
+ void setupDocumentView(QWidget* parent) {
+ mDocumentView = new DocumentView(parent);
+ connect(mDocumentView, SIGNAL(completed()),
+ mWindow, SLOT(slotPartCompleted()) );
+ connect(mDocumentView, SIGNAL(partChanged(KParts::Part*)),
+ mWindow, SLOT(createGUI(KParts::Part*)) );
+ connect(mDocumentView, SIGNAL(previousImageRequested()),
+ mWindow, SLOT(goToPrevious()) );
+ connect(mDocumentView, SIGNAL(nextImageRequested()),
+ mWindow, SLOT(goToNext()) );
+
+ ThumbnailBarView* bar = mDocumentView->thumbnailBar();
+ bar->setModel(mDirModel);
+ bar->setThumbnailViewHelper(mThumbnailViewHelper);
+ bar->setSelectionModel(mThumbnailView->selectionModel());
+ }
+
void setupFilterBar() {
mFilterBar = new QWidget(mThumbnailViewPanel);
mFilterBar->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed );
@@ -379,6 +391,12 @@ struct MainWindow::Private {
mShowFilterBar->setShortcut(Qt::CTRL | Qt::Key_I);
connect(mShowFilterBar, SIGNAL(triggered(bool)), mWindow, SLOT(toggleFilterBarVisibility(bool)));
+ mToggleThumbnailBarAction = actionCollection->add<KToggleAction>("toggle_thumbnailbar");
+ mToggleThumbnailBarAction->setText(i18n("Show Thumbnail Bar"));
+ mToggleThumbnailBarAction->setShortcut(Qt::CTRL | Qt::Key_T);
+ connect(mToggleThumbnailBarAction, SIGNAL(triggered(bool)),
+ mDocumentView->thumbnailBar(), SLOT(setVisible(bool)));
+
KStandardAction::keyBindings(mWindow->guiFactory(),
SLOT(configureShortcuts()), actionCollection);
@@ -515,16 +533,35 @@ struct MainWindow::Private {
void createFullScreenBar() {
mFullScreenBar = new FullScreenBar(mDocumentView);
- mFullScreenBar->addAction(mFullScreenAction);
- mFullScreenBar->addAction(mGoToPreviousAction);
- mFullScreenBar->addAction(mGoToNextAction);
-
- mFullScreenBar->addSeparator();
- mFullScreenBar->addAction(mToggleSlideShowAction);
- mFullScreenBar->addWidget(mSlideShow->intervalWidget());
- mFullScreenBar->addWidget(mSlideShow->optionsWidget());
+ QWidget* container = new QWidget;
+ QToolBar* bar = new QToolBar;
+ bar->setFloatable(false);
+ bar->setIconSize(QSize(32, 32));
+ bar->addAction(mFullScreenAction);
+ bar->addAction(mGoToPreviousAction);
+ bar->addAction(mGoToNextAction);
+
+ bar->addSeparator();
+ bar->addAction(mToggleSlideShowAction);
+ bar->addWidget(mSlideShow->intervalWidget());
+ bar->addWidget(mSlideShow->optionsWidget());
+
+ ThumbnailBarView* view = new ThumbnailBarView(container);
+ ThumbnailBarItemDelegate* delegate = new ThumbnailBarItemDelegate(view);
+ view->setModel(mDirModel);
+ view->setThumbnailViewHelper(mThumbnailViewHelper);
+ view->setItemDelegate(delegate);
+ view->setSelectionModel(mThumbnailView->selectionModel());
+ view->setThumbnailSize(64);
+
+ QGridLayout* layout = new QGridLayout(container);
+ layout->setMargin(0);
+ layout->setSpacing(0);
+ layout->addWidget(bar, 0, 0);
+ layout->addWidget(mInformationLabel, 1, 0);
+ layout->addWidget(view, 0, 1, 2, 1);
- mFullScreenBar->addWidget(mInformationLabel);
+ mFullScreenBar->addWidget(container);
mFullScreenBar->resize(mFullScreenBar->sizeHint());
}
@@ -1041,6 +1078,7 @@ void MainWindow::toggleFullScreen() {
d->mStateBeforeFullScreen.mActiveViewModeAction = d->mViewModeActionGroup->checkedAction();
d->mStateBeforeFullScreen.mSideBarVisible = d->mSideBarContainer->isVisible();
d->mStateBeforeFullScreen.mWindowState = windowState();
+ d->mStateBeforeFullScreen.mThumbnailBarVisible = d->mToggleThumbnailBarAction->isChecked();
d->mDocumentView->setViewBackgroundColor(Qt::black);
@@ -1052,9 +1090,13 @@ void MainWindow::toggleFullScreen() {
toolBar()->hide();
d->mDocumentView->setStatusBarVisible(false);
d->mSaveBar->setForceHide(true);
+ if (d->mToggleThumbnailBarAction->isChecked()) {
+ d->mToggleThumbnailBarAction->trigger();
+ }
if (!d->mFullScreenBar) {
d->createFullScreenBar();
}
+ d->mToggleThumbnailBarAction->setEnabled(false);
d->mFullScreenBar->setActivated(true);
updateFullScreenInformation();
} else {
@@ -1064,12 +1106,17 @@ void MainWindow::toggleFullScreen() {
// Back to normal
d->mDocumentView->setViewBackgroundColor(GwenviewConfig::viewBackgroundColor());
d->mSlideShow->stop();
+ if (d->mStateBeforeFullScreen.mThumbnailBarVisible) {
+ d->mToggleThumbnailBarAction->trigger();
+ }
d->mSaveBar->setForceHide(false);
d->mFullScreenBar->setActivated(false);
setWindowState(d->mStateBeforeFullScreen.mWindowState);
d->mDocumentView->setStatusBarVisible(true);
menuBar()->setVisible(d->mShowMenuBarAction->isChecked());
toolBar()->show();
+
+ d->mToggleThumbnailBarAction->setEnabled(true);
}
setUpdatesEnabled(true);
}
diff --git a/gwenview/app/thumbnailbarview.cpp b/gwenview/app/thumbnailbarview.cpp
new file mode 100644
index 0000000..b3a2605
--- /dev/null
+++ b/gwenview/app/thumbnailbarview.cpp
@@ -0,0 +1,331 @@
+// vim: set tabstop=4 shiftwidth=4 noexpandtab:
+/*
+Gwenview: an image viewer
+Copyright 2008 Aurélien Gâteau <[email protected]>
+
+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.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Cambridge, MA 02110-1301, USA.
+
+*/
+// Self
+#include "thumbnailbarview.moc"
+
+// Qt
+#include <QApplication>
+#include <QHelpEvent>
+#include <QScrollBar>
+#include <QPainter>
+#include <QWindowsStyle>
+#include <QToolTip>
+// KDE
+
+// Local
+#include "lib/paintutils.h"
+#include "lib/thumbnailview/abstractthumbnailviewhelper.h"
+
+namespace Gwenview {
+
+/**
+ * Space between the item outer rect and the content, and between the
+ * thumbnail and the caption
+ */
+const int ITEM_MARGIN = 5;
+
+/** How dark is the shadow, 0 is invisible, 255 is as dark as possible */
+const int SHADOW_STRENGTH = 127;
+
+/** How many pixels around the thumbnail are shadowed */
+const int SHADOW_SIZE = 3;
+
+
+static QString rgba(const QColor &color) {
+ QString rgba("rgba(%1, %2, %3, %4)");
+ return rgba.arg(QString::number(color.red()), QString::number(color.green()), QString::number(color.red()), QString::number(color.alpha()));
+}
+
+
+struct ThumbnailBarItemDelegatePrivate {
+ // Key is height * 1000 + width
+ typedef QMap<int, QPixmap> ShadowCache;
+ mutable ShadowCache mShadowCache;
+
+ ThumbnailBarItemDelegate* mDelegate;
+ ThumbnailView* mView;
+ int mThumbnailSize;
+ QColor borderColor;
+
+ void showToolTip(QHelpEvent* helpEvent) {
+ QModelIndex index = mView->indexAt(helpEvent->pos());
+ if (!index.isValid()) {
+ return;
+ }
+ QString fullText = index.data().toString();
+ QRect rect = mView->visualRect(index);
+ QPoint pos = QCursor::pos();
+ QToolTip::showText(pos, fullText, mView);
+ }
+
+ void drawShadow(QPainter* painter, const QRect& rect) const {
+ const QPoint shadowOffset(-SHADOW_SIZE, -SHADOW_SIZE + 1);
+
+ int key = rect.height() * 1000 + rect.width();
+
+ ShadowCache::Iterator it = mShadowCache.find(key);
+ if (it == mShadowCache.end()) {
+ QSize size = QSize(rect.width() + 2*SHADOW_SIZE, rect.height() + 2*SHADOW_SIZE);
+ QColor color(0, 0, 0, SHADOW_STRENGTH);
+ QPixmap shadow = PaintUtils::generateFuzzyRect(size, color, SHADOW_SIZE);
+ it = mShadowCache.insert(key, shadow);
+ }
+ painter->drawPixmap(rect.topLeft() + shadowOffset, it.value());
+ }
+};
+
+
+ThumbnailBarItemDelegate::ThumbnailBarItemDelegate(ThumbnailView* view)
+: d(new ThumbnailBarItemDelegatePrivate) {
+ d->mDelegate = this;
+ d->mView = view;
+ view->viewport()->installEventFilter(this);
+ setThumbnailSize(view->thumbnailSize());
+
+ QWidget* viewport = view->viewport();
+ QColor bgColor = viewport->palette().color(viewport->backgroundRole());
+
+ if (bgColor.value() < 128) {
+ d->borderColor = bgColor.darker(200);
+ } else {
+ d->borderColor = bgColor.lighter(200);
+ }
+ d->borderColor = PaintUtils::adjustedHsv(d->borderColor, 0, - d->borderColor.saturation(), 0);
+
+ connect(view, SIGNAL(thumbnailSizeChanged(int)),
+ SLOT(setThumbnailSize(int)) );
+}
+
+
+QSize ThumbnailBarItemDelegate::sizeHint( const QStyleOptionViewItem & /*option*/, const QModelIndex & /*index*/) const {
+ return d->mView->gridSize();
+}
+
+
+void ThumbnailBarItemDelegate::setThumbnailSize(int value) {
+ d->mThumbnailSize = value;
+ d->mView->setGridSize(QSize(value + ITEM_MARGIN*2 + 1, value + ITEM_MARGIN*2 + 1));
+}
+
+
+bool ThumbnailBarItemDelegate::eventFilter(QObject*, QEvent* event) {
+ if (event->type() == QEvent::ToolTip) {
+ QHelpEvent* helpEvent = static_cast<QHelpEvent*>(event);
+ d->showToolTip(helpEvent);
+ return true;
+
+ } else if (event->type() == QEvent::Wheel) {
+ QScrollBar* hsb = d->mView->horizontalScrollBar();
+ QWheelEvent* wheelEvent = static_cast<QWheelEvent*>(event);
+ hsb->setValue(hsb->value() - wheelEvent->delta());
+ return true;
+ }
+
+ return false;
+}
+
+
+void ThumbnailBarItemDelegate::paint( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const {
+ ThumbnailView::Thumbnail thumbnail = d->mView->thumbnailForIndex(index);
+ QPixmap thumbnailPix = thumbnail.mPixmap;
+ QSize thumbnailSize = d->mView->gridSize() - QSize(ITEM_MARGIN*2 + 1, ITEM_MARGIN*3 + 1);
+ if (thumbnailPix.width() > thumbnailSize.width() || thumbnailPix.height() > thumbnailSize.height()) {
+ thumbnailPix = thumbnailPix.scaled(thumbnailSize, Qt::KeepAspectRatio);
+ }
+ QRect rect = option.rect;
+
+ QStyleOptionViewItemV4 opt = option;
+ const QWidget* widget = opt.widget;
+ QStyle* style = widget ? widget->style() : QApplication::style();
+ style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, widget);
+
+ // Draw thumbnail
+ if (!thumbnailPix.isNull()) {
+ QRect thumbnailRect = QRect(
+ rect.left() + (rect.width() - thumbnailPix.width())/2,
+ rect.top() + (rect.height() - thumbnailPix.height())/2 ,
+ thumbnailPix.width(),
+ thumbnailPix.height());
+
+ if (/*!(option.state & QStyle::State_Selected) && */ thumbnail.mOpaque) {
+ d->drawShadow(painter, thumbnailRect);
+ }
+
+ if (thumbnail.mOpaque) {
+ painter->setPen(d->borderColor);
+ painter->setRenderHint(QPainter::Antialiasing, false);
+ QRect borderRect = thumbnailRect.adjusted(-1, -1, 0, 0);
+ painter->drawRect(borderRect);
+ }
+ painter->drawPixmap(thumbnailRect.left(), thumbnailRect.top(), thumbnailPix);
+ }
+}
+
+
+ThumbnailBarItemDelegate::~ThumbnailBarItemDelegate() {
+ delete d;
+}
+
+
+ThumbnailBarView::ThumbnailBarView(QWidget* parent)
+: ThumbnailView(parent) {
+ setObjectName("thumbnailBarView");
+ setUniformItemSizes(true);
+ setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
+ setWrapping(false);
+ setThumbnailSize(80);
+
+ QStyle* defaultStyle = style();
+ setStyle(mStyle = new QWindowsStyle);
+ setStyleSheet(defaultStyleSheet());
+ horizontalScrollBar()->setStyle(defaultStyle);
+
+ // Since QWindowsStyle is used context menu won't be painted by system style. Avoid it by this hack:
+ ThumbnailView::disconnect(SIGNAL(customContextMenuRequested(const QPoint&)));
+ connect(this, SIGNAL(customContextMenuRequested(const QPoint&)),
+ SLOT(showContextMenu()) );
+}
+
+
+ThumbnailBarView::~ThumbnailBarView() {
+ delete mStyle;
+}
+
+
+void ThumbnailBarView::showContextMenu() {
+ // Using parentWidget as parent of menu to paint it by system style.
+ thumbnailViewHelper()->showContextMenu(parentWidget());
+}
+
+
+QSize ThumbnailBarView::sizeHint() const {
+ QSize hint = ThumbnailView::sizeHint();
+ int size = gridSize().height();
+ int hsbExt = horizontalScrollBar()->sizeHint().height();
+ int f = 2 * frameWidth();
+ hint.setHeight(size + f + hsbExt);
+ return hint;
+}
+
+
+QString ThumbnailBarView::defaultStyleSheet() const {
+ QColor bgColor, bgSelColor;
+ bgSelColor = viewport()->palette().color(QPalette::Normal, QPalette::Highlight);
+ bgColor = viewport()->palette().color(viewport()->backgroundRole());
+
+ // Avoid dark and bright colors
+ bgColor.setHsv(bgColor.hue(), bgColor.saturation(), (128 * 2 + bgColor.value()) / 3);
+ bgSelColor.setHsv(bgSelColor.hue(), bgSelColor.saturation(), (128 * 2 + bgSelColor.value()) / 3);
+
+
+ QString itemCss =
+ "QListView::item {"
+ " background-color:"
+ " qlineargradient(x1:0, y1:0, x2:0, y2:1,"
+ " stop: 0 black, stop: 0.05 %1, stop:1 %2);"
+ " border-left: 1px solid "
+ " qlineargradient(x1:0, y1:0, x2:0, y2:1,"
+ " stop: 0 black, stop: 0.05 %3, stop:1 %4);"
+ " border-right: 1px solid "
+ " qlineargradient(x1:0, y1:0, x2:0, y2:1,"
+ " stop: 0 black, stop: 0.05 %4, stop:1 %5);"
+ "}";
+ itemCss = itemCss.arg(
+ bgColor.lighter(125).name(),
+ bgColor.darker(125).name(),
+ bgColor.lighter(170).name(),
+ bgColor.name(),
+ bgColor.darker(170).name());
+
+ QString viewCss =
+ "#thumbnailBarView {"
+ " background-color:"
+ " qlineargradient(x1:0, y1:0, x2:0, y2:1,"
+ " stop: 0 black, stop: 0.05 %1, stop:1 %2);"
+ " border: 1px solid #444;"
+ "}";
+ viewCss = viewCss.arg(bgColor.darker(125).name(), bgColor.name());
+
+ QColor borderSelColor(0, 0, 0, 127);
+ QString itemSelCss =
+ "QListView::item:selected {"
+ " background-color:"
+ " qlineargradient(x1:0, y1:0, x2:0, y2:1,"
+ " stop: 0 black, stop: 0.05 %1, stop:1 %2);"
+ " border-left: 1px solid %3;"
+ " border-right: 1px solid %3;"
+ "}";
+ itemSelCss = itemSelCss.arg(
+ bgSelColor.lighter(125).name(),
+ bgSelColor.darker(125).name(),
+ rgba(borderSelColor));
+
+ QString scrollbarCss =
+ "QScrollBar:horizontal {"
+ " background-color:"
+ " qlineargradient(x1:0, y1:0, x2:0, y2:1,"
+ " stop: 0 black, stop: 0.4 %1, stop: 1 %2);"
+ " height: 8px;"
+ " border-top: 1px solid black;"
+ "}";
+ scrollbarCss = scrollbarCss.arg(bgColor.darker(200).name(), bgColor.darker(175).name());
+
+ QString handle =
+ "background:"
+ " qlineargradient(x1:0, y1:0, x2:0, y2:1,"
+ " stop: 0 %1, stop: 0.17 %2,"
+ " stop: 0.2 %3, stop: 0.8 %4,"
+ " stop: 0.83 %2, stop: 1 %1);"
+ "border: 1px solid"
+ " qlineargradient(x1:0, y1:0, x2:0, y2:1,"
+ " stop: 0 #242424, stop: 0.2 %2,"
+ " stop: 0.70 %2, stop: 1 #242424);"
+ "border-top: 0px;"
+ "border-bottom: 0px;"
+ "}";
+
+ QColor handleBase = QColor::fromHsv(bgColor.hue(), bgColor.saturation() / 2, (bgColor.value() + 255) / 2);
+ QColor handleSelBase = handleBase.lighter(110);
+ QString handleCss =
+ "QScrollBar::add-line:horizontal, QScrollBar::sub-line:horizontal, QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal {"
+ " width: 0;"
+ " border: 0;"
+ "}"
+ "QScrollBar::handle:horizontal {"
+ " min-width: 20px;" +
+ handle.arg(
+ handleBase.darker(170).name(),
+ handleBase.darker(125).name(),
+ handleBase.darker(140).name(),
+ handleBase.lighter(115).name()) +
+ "QScrollBar::handle:hover {" +
+ handle.arg(
+ handleSelBase.darker(170).name(),
+ handleSelBase.darker(125).name(),
+ handleSelBase.darker(140).name(),
+ handleSelBase.lighter(115).name());
+
+ return viewCss + itemCss + itemSelCss + scrollbarCss + handleCss;
+}
+
+
+} // namespace
diff --git a/gwenview/app/thumbnailbarview.h b/gwenview/app/thumbnailbarview.h
new file mode 100644
index 0000000..adaae93
--- /dev/null
+++ b/gwenview/app/thumbnailbarview.h
@@ -0,0 +1,76 @@
+// vim: set tabstop=4 shiftwidth=4 noexpandtab:
+/*
+Gwenview: an image viewer
+Copyright 2008 Aurélien Gâteau <[email protected]>
+
+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.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Cambridge, MA 02110-1301, USA.
+
+*/
+#ifndef THUMBNAILBARVIEW_H
+#define THUMBNAILBARVIEW_H
+
+// Qt
+#include <QAbstractItemDelegate>
+
+// KDE
+
+// Local
+#include <lib/thumbnailview/thumbnailview.h>
+
+namespace Gwenview {
+
+
+class ThumbnailBarItemDelegatePrivate;
+
+class ThumbnailBarItemDelegate : public QAbstractItemDelegate {
+ Q_OBJECT
+public:
+ ThumbnailBarItemDelegate(ThumbnailView*);
+ ~ThumbnailBarItemDelegate();
+
+ virtual void paint( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const;
+ virtual QSize sizeHint( const QStyleOptionViewItem & /*option*/, const QModelIndex & /*index*/ ) const;
+
+private Q_SLOTS:
+ void setThumbnailSize(int);
+
+protected:
+ virtual bool eventFilter(QObject*, QEvent*);
+
+private:
+ ThumbnailBarItemDelegatePrivate* const d;
+ friend class ThumbnailBarItemDelegatePrivate;
+};
+
+
+class ThumbnailBarView : public ThumbnailView {
+ Q_OBJECT
+public:
+ ThumbnailBarView(QWidget *);
+ ~ThumbnailBarView();
+
+ QSize sizeHint() const;
+
+private Q_SLOTS:
+ void showContextMenu();
+
+private:
+ QStyle* mStyle;
+ QString defaultStyleSheet() const;
+};
+
+} // namespace
+
+#endif /* THUMBNAILBARVIEW_H */
diff --git a/gwenview/lib/fullscreenbar.cpp b/gwenview/lib/fullscreenbar.cpp
index 9242167..44e73b4 100644
--- a/gwenview/lib/fullscreenbar.cpp
+++ b/gwenview/lib/fullscreenbar.cpp
@@ -23,6 +23,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
// Qt
#include <QApplication>
+#include <QDesktopWidget>
#include <QBitmap>
#include <QEvent>
#include <QHBoxLayout>
@@ -74,11 +75,14 @@ FullScreenBar::FullScreenBar(QWidget* parent)
" background-color:"
" qlineargradient(x1:0, y1:0, x2:0, y2:1,"
" stop:0 #444, stop: 0.6 black, stop:1 black);"
- " border-right: 1px solid #ccc;"
- " border-bottom: 1px solid #ccc;"
- " padding-right: 2px;"
- " padding-bottom: 2px;"
- " border-bottom-right-radius: 4px;"
+ " border: 0px;"
+ " border-bottom: 1px solid gray;"
+ " padding: 0px;"
+ "}"
+
+ "QToolBar {"
+ " margin: 0px;"
+ " padding: 0px;"
"}"
"QToolButton {"
@@ -117,6 +121,10 @@ FullScreenBar::~FullScreenBar() {
delete d;
}
+QSize FullScreenBar::sizeHint() const {
+ int width = QApplication::desktop()->screenGeometry(this).width();
+ return QSize(width, QFrame::sizeHint().height());
+}
void FullScreenBar::moveBar(qreal value) {
move(0, -height() + int(value * height()) );
diff --git a/gwenview/lib/fullscreenbar.h b/gwenview/lib/fullscreenbar.h
index f5ef11a..1ece8d9 100644
--- a/gwenview/lib/fullscreenbar.h
+++ b/gwenview/lib/fullscreenbar.h
@@ -48,6 +48,7 @@ public:
void addSeparator();
void addWidget(QWidget*);
+ QSize sizeHint() const;
public Q_SLOTS:
void slideIn();
void slideOut();