From 2f4d6bbe535a195046b4746fd3a771087ee4a6c4 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Sat, 27 Apr 2013 12:27:27 -0300 Subject: Added support for showing the Stars on the DiveTable For the stars on the dive table I had to rework a bit my StarRating widget, because it used a pixmap for each widget that were created. Not it uses only 2 pixmaps: the active and inactive ones. A new file was created named modeldelegates(h, cpp) that should hold all delegates of the models. For the GTK / C folks, a 'Delegate' ia s way to bypass the default behavior of the view that's displaying the data. I also added the code to display the stars if no delegate is set ( good for debugging. ) Signed-off-by: Tomaz Canabrava --- Makefile | 2 ++ qt-ui/divelistview.cpp | 2 ++ qt-ui/mainwindow.cpp | 3 ++- qt-ui/modeldelegates.cpp | 36 +++++++++++++++++++++++++ qt-ui/modeldelegates.h | 12 +++++++++ qt-ui/models.cpp | 19 +++++++++---- qt-ui/models.h | 5 ++-- qt-ui/starwidget.cpp | 70 +++++++++++++++++++++++------------------------- qt-ui/starwidget.h | 15 ++++------- 9 files changed, 110 insertions(+), 54 deletions(-) create mode 100644 qt-ui/modeldelegates.cpp create mode 100644 qt-ui/modeldelegates.h diff --git a/Makefile b/Makefile index 6ebba4dd5..aac1759bc 100644 --- a/Makefile +++ b/Makefile @@ -37,6 +37,7 @@ HEADERS = \ qt-ui/models.h \ qt-ui/plotareascene.h \ qt-ui/starwidget.h \ + qt-ui/modeldelegates.h \ SOURCES = \ @@ -75,6 +76,7 @@ SOURCES = \ qt-ui/models.cpp \ qt-ui/plotareascene.cpp \ qt-ui/starwidget.cpp \ + qt-ui/modeldelegates.cpp \ $(RESFILE) diff --git a/qt-ui/divelistview.cpp b/qt-ui/divelistview.cpp index 676d7c463..e8a3d2311 100644 --- a/qt-ui/divelistview.cpp +++ b/qt-ui/divelistview.cpp @@ -5,6 +5,8 @@ * */ #include "divelistview.h" +#include "models.h" +#include "modeldelegates.h" DiveListView::DiveListView(QWidget *parent) : QTreeView(parent) { diff --git a/qt-ui/mainwindow.cpp b/qt-ui/mainwindow.cpp index 8cdc60193..4c4143e98 100644 --- a/qt-ui/mainwindow.cpp +++ b/qt-ui/mainwindow.cpp @@ -20,7 +20,7 @@ #include "../dive.h" #include "../divelist.h" #include "../pref.h" - +#include "modeldelegates.h" MainWindow::MainWindow() : ui(new Ui::MainWindow()), model(new DiveTripModel(this)), @@ -69,6 +69,7 @@ void MainWindow::on_actionOpen_triggered() model->deleteLater(); model = new DiveTripModel(this); sortModel->setSourceModel(model); + ui->ListWidget->setItemDelegateForColumn(DiveTripModel::RATING, new StarWidgetsDelegate()); } void MainWindow::on_actionSave_triggered() diff --git a/qt-ui/modeldelegates.cpp b/qt-ui/modeldelegates.cpp new file mode 100644 index 000000000..1bbf1061b --- /dev/null +++ b/qt-ui/modeldelegates.cpp @@ -0,0 +1,36 @@ +#include "modeldelegates.h" +#include "../dive.h" +#include "../divelist.h" +#include "starwidget.h" +#include "models.h" + +#include +#include + +void StarWidgetsDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const +{ + if (!index.isValid()){ + return; + } + + int rating = index.model()->data(index, DiveTripModel::DelegatesRole).toInt(); + + if (option.state & QStyle::State_Selected) + painter->fillRect(option.rect, option.palette.highlight()); + + painter->save(); + painter->setRenderHint(QPainter::Antialiasing, true); + + for(int i = 0; i < rating; i++) + painter->drawPixmap(option.rect.x() + i * IMG_SIZE + SPACING, option.rect.y(), StarWidget::starActive()); + + for(int i = rating; i < TOTALSTARS; i++) + painter->drawPixmap(option.rect.x() + i * IMG_SIZE + SPACING, option.rect.y(), StarWidget::starInactive()); + + painter->restore(); +} + +QSize StarWidgetsDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const +{ + return QSize(IMG_SIZE * TOTALSTARS + SPACING * (TOTALSTARS-1), IMG_SIZE); +} diff --git a/qt-ui/modeldelegates.h b/qt-ui/modeldelegates.h new file mode 100644 index 000000000..eacbb5a1e --- /dev/null +++ b/qt-ui/modeldelegates.h @@ -0,0 +1,12 @@ +#ifndef MODELDELEGATES_H +#define MODELDELEGATES_H + +#include + +class StarWidgetsDelegate : public QAbstractItemDelegate { + Q_OBJECT +public: + virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const; + virtual QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const; +}; +#endif diff --git a/qt-ui/models.cpp b/qt-ui/models.cpp index 5f803766f..0944fe3e3 100644 --- a/qt-ui/models.cpp +++ b/qt-ui/models.cpp @@ -5,9 +5,6 @@ * */ #include "models.h" -#include "../dive.h" -#include "../divelist.h" - #include extern struct tank_info tank_info[100]; @@ -284,6 +281,7 @@ void TankInfoModel::update() } } + /*! A DiveItem for use with a DiveTripModel * * A simple class which wraps basic stats for a dive (e.g. duration, depth) and @@ -314,6 +312,8 @@ public: return tw.grams; } + int diveRating() const { return dive->rating; } + QString displayDuration() const; QString displayDepth() const; QString displayTemperature() const; @@ -335,6 +335,7 @@ private: QList childlist; }; + DiveItem::DiveItem(struct dive *d, DiveItem *p): dive(d), parentItem(p) @@ -490,6 +491,16 @@ QVariant DiveTripModel::data(const QModelIndex &index, int role) const case LOCATION: retVal = item->diveLocation(); break; + case RATING: + retVal = item->diveRating(); + break; + } + } + if (role == DelegatesRole){ + switch(index.column()){ + case RATING: + retVal = item->diveRating(); + break; } } return retVal; @@ -569,8 +580,6 @@ int DiveTripModel::rowCount(const QModelIndex &parent) const return item ? item->children().count() : 0; } - - int DiveTripModel::columnCount(const QModelIndex &parent) const { return parent.isValid() && parent.column() != 0 ? 0 : COLUMNS; diff --git a/qt-ui/models.h b/qt-ui/models.h index d64faf0bd..f4d9c8d3b 100644 --- a/qt-ui/models.h +++ b/qt-ui/models.h @@ -9,7 +9,7 @@ #include #include "../dive.h" - +#include "../divelist.h" /* Encapsulates the tank_info global variable * to show on Qt`s Model View System.*/ class TankInfoModel : public QAbstractTableModel { @@ -74,11 +74,12 @@ private: /*! An AbstractItemModel for recording dive trip information such as a list of dives. * */ -class DiveItem; // Represents a single item on the model, implemented in the .cpp since it's private for this class. +class DiveItem; class DiveTripModel : public QAbstractItemModel { public: enum Column {NR, DATE, RATING, DEPTH, DURATION, TEMPERATURE, TOTALWEIGHT, SUIT, CYLINDER, NITROX, SAC, OTU, MAXCNS, LOCATION, COLUMNS }; + enum { DelegatesRole = Qt::UserRole }; DiveTripModel(QObject *parent = 0); diff --git a/qt-ui/starwidget.cpp b/qt-ui/starwidget.cpp index 866fb5834..4d1fa066c 100644 --- a/qt-ui/starwidget.cpp +++ b/qt-ui/starwidget.cpp @@ -5,32 +5,29 @@ #include #include -int StarWidget::currentStars() const -{ - return current; -} +QPixmap* StarWidget::activeStar = 0; +QPixmap* StarWidget::inactiveStar = 0; -void StarWidget::enableHalfStars(bool enabled) +QPixmap StarWidget::starActive() { - halfStar = enabled; - update(); + return (*activeStar); } -bool StarWidget::halfStarsEnabled() const +QPixmap StarWidget::starInactive() { - return halfStar; + return (*inactiveStar); } -int StarWidget::maxStars() const +int StarWidget::currentStars() const { - return stars; + return current; } void StarWidget::mouseReleaseEvent(QMouseEvent* event) { int starClicked = event->pos().x() / IMG_SIZE + 1; - if (starClicked > stars) - starClicked = stars; + if (starClicked > TOTALSTARS) + starClicked = TOTALSTARS; if (current == starClicked) current -= 1; @@ -45,10 +42,10 @@ void StarWidget::paintEvent(QPaintEvent* event) QPainter p(this); for(int i = 0; i < current; i++) - p.drawPixmap(i * IMG_SIZE + SPACING, 0, activeStar); + p.drawPixmap(i * IMG_SIZE + SPACING, 0, starActive()); - for(int i = current; i < stars; i++) - p.drawPixmap(i * IMG_SIZE + SPACING, 0, inactiveStar); + for(int i = current; i < TOTALSTARS; i++) + p.drawPixmap(i * IMG_SIZE + SPACING, 0, starInactive()); } void StarWidget::setCurrentStars(int value) @@ -58,27 +55,25 @@ void StarWidget::setCurrentStars(int value) Q_EMIT valueChanged(current); } -void StarWidget::setMaximumStars(int maximum) -{ - stars = maximum; - update(); -} - StarWidget::StarWidget(QWidget* parent, Qt::WindowFlags f): QWidget(parent, f), - stars(5), - current(0), - halfStar(false) + current(0) { - QSvgRenderer render(QString(":star")); - QPixmap renderedStar(IMG_SIZE, IMG_SIZE); + if(!activeStar){ + activeStar = new QPixmap(); + QSvgRenderer render(QString(":star")); + QPixmap renderedStar(IMG_SIZE, IMG_SIZE); - renderedStar.fill(Qt::transparent); - QPainter painter(&renderedStar); + renderedStar.fill(Qt::transparent); + QPainter painter(&renderedStar); - render.render(&painter, QRectF(0, 0, IMG_SIZE, IMG_SIZE)); - activeStar = renderedStar; - inactiveStar = grayImage(&renderedStar); + render.render(&painter, QRectF(0, 0, IMG_SIZE, IMG_SIZE)); + (*activeStar) = renderedStar; + } + if(!inactiveStar){ + inactiveStar = new QPixmap(); + (*inactiveStar) = grayImage(activeStar); + } } QPixmap StarWidget::grayImage(QPixmap* coloredImg) @@ -86,17 +81,20 @@ QPixmap StarWidget::grayImage(QPixmap* coloredImg) QImage img = coloredImg->toImage(); for (int i = 0; i < img.width(); ++i) { for (int j = 0; j < img.height(); ++j) { - QRgb col = img.pixel(i, j); - if (!col) + QRgb rgb = img.pixel(i, j); + if (!rgb) continue; - int gray = QColor(Qt::darkGray).rgb(); + + QColor c(rgb); + int gray = (c.red() + c.green() + c.blue()) / 3; img.setPixel(i, j, qRgb(gray, gray, gray)); } } + return QPixmap::fromImage(img); } QSize StarWidget::sizeHint() const { - return QSize(IMG_SIZE * stars + SPACING * (stars-1), IMG_SIZE); + return QSize(IMG_SIZE * TOTALSTARS + SPACING * (TOTALSTARS-1), IMG_SIZE); } diff --git a/qt-ui/starwidget.h b/qt-ui/starwidget.h index cdbb3ab5c..d92be5a98 100644 --- a/qt-ui/starwidget.h +++ b/qt-ui/starwidget.h @@ -3,39 +3,34 @@ #include +enum StarConfig {SPACING = 2, IMG_SIZE = 16, TOTALSTARS = 5}; class StarWidget : public QWidget { Q_OBJECT public: explicit StarWidget(QWidget* parent = 0, Qt::WindowFlags f = 0); - - int maxStars() const; int currentStars() const; - bool halfStarsEnabled() const; /*reimp*/ QSize sizeHint() const; - enum {SPACING = 2, IMG_SIZE = 16}; + static QPixmap starActive(); + static QPixmap starInactive(); Q_SIGNALS: void valueChanged(int stars); public Q_SLOTS: void setCurrentStars(int value); - void setMaximumStars(int maximum); - void enableHalfStars(bool enabled); protected: /*reimp*/ void mouseReleaseEvent(QMouseEvent* ); /*reimp*/ void paintEvent(QPaintEvent* ); private: - int stars; int current; - bool halfStar; - QPixmap activeStar; - QPixmap inactiveStar; + static QPixmap* activeStar; + static QPixmap* inactiveStar; QPixmap grayImage(QPixmap *coloredImg); }; -- cgit v1.2.3-70-g09d2