From d39b09c5bcb2aafe95adaf67f6730050cccbd93a Mon Sep 17 00:00:00 2001 From: csoler Date: Tue, 23 Jun 2020 20:24:14 +0200 Subject: [PATCH] added zoom of thumbnails on control+wheel --- retroshare-gui/src/gui/common/RSTreeView.cpp | 8 +++ retroshare-gui/src/gui/common/RSTreeView.h | 2 + .../src/gui/gxs/GxsGroupFrameDialog.cpp | 49 ++++++++++--------- .../src/gui/gxs/GxsGroupFrameDialog.h | 5 +- .../src/gui/gxs/GxsMessageFrameWidget.h | 1 + .../GxsChannelPostsWidgetWithModel.cpp | 47 ++++++++++++++++-- .../GxsChannelPostsWidgetWithModel.h | 8 ++- .../GxsChannelPostsWidgetWithModel.ui | 4 +- 8 files changed, 91 insertions(+), 33 deletions(-) diff --git a/retroshare-gui/src/gui/common/RSTreeView.cpp b/retroshare-gui/src/gui/common/RSTreeView.cpp index 36034166f..d54987c3e 100644 --- a/retroshare-gui/src/gui/common/RSTreeView.cpp +++ b/retroshare-gui/src/gui/common/RSTreeView.cpp @@ -27,6 +27,14 @@ RSTreeView::RSTreeView(QWidget *parent) : QTreeView(parent) setMouseTracking(false); // normally the default, but who knows if it's not goign to change in the future. } +void RSTreeView::wheelEvent(QWheelEvent *e) +{ + if(e->modifiers() == Qt::ControlModifier) + emit zoomRequested(e->delta() > 0); + else + QTreeView::wheelEvent(e); +} + void RSTreeView::mouseMoveEvent(QMouseEvent *e) { QModelIndex idx = indexAt(e->pos()); diff --git a/retroshare-gui/src/gui/common/RSTreeView.h b/retroshare-gui/src/gui/common/RSTreeView.h index f7942ef64..116ccac31 100644 --- a/retroshare-gui/src/gui/common/RSTreeView.h +++ b/retroshare-gui/src/gui/common/RSTreeView.h @@ -40,9 +40,11 @@ public: signals: void sizeChanged(QSize); + void zoomRequested(bool zoom_or_unzoom); protected: virtual void mouseMoveEvent(QMouseEvent *e) override; // overriding so as to manage auto-selection + virtual void wheelEvent(QWheelEvent *e) override; // overriding so as to manage zoom virtual void resizeEvent(QResizeEvent *e) override; virtual void paintEvent(QPaintEvent *event) override; diff --git a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp index ed00e16d1..a2be34e8b 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp @@ -390,6 +390,7 @@ static uint32_t checkDelay(uint32_t time_in_secs) return 365 * 86400; } + void GxsGroupFrameDialog::groupTreeCustomPopupMenu(QPoint point) { // First separately handle the case of search top level items @@ -433,11 +434,12 @@ void GxsGroupFrameDialog::groupTreeCustomPopupMenu(QPoint point) QAction *action; #ifdef TODO - if (mMessageWidget) { - action = contextMnu.addAction(QIcon(IMAGE_TABNEW), tr("Open in new tab"), this, SLOT(openInNewTab())); - if (mGroupId.isNull() || messageWidget(mGroupId, true)) { + if (mMessageWidget) + { + action = contextMnu.addAction(QIcon(IMAGE_TABNEW), tr("Open new tab"), this, SLOT(openInNewTab())); + + if (mGroupId.isNull() || messageWidget(mGroupId, true)) // dont enable the open in tab if a tab is already here action->setEnabled(false); - } } #endif @@ -841,20 +843,19 @@ void GxsGroupFrameDialog::changedCurrentGroup(const QString& groupId) /* search exisiting tab */ GxsMessageFrameWidget *msgWidget = messageWidget(mGroupId, true); - if (!msgWidget) + // check that we have at least one tab + if(!currentWidget()) + msgWidget = createMessageWidget(RsGxsGroupId(groupId.toStdString())); + + if (msgWidget) + ui->messageTabWidget->setCurrentWidget(msgWidget); + else { - if (mMessageWidget) - { - /* not found, use standard tab */ - msgWidget = mMessageWidget; - msgWidget->setGroupId(mGroupId); - } else { - /* create new tab */ - msgWidget = createMessageWidget(mGroupId); - } + msgWidget = currentWidget(); + msgWidget->setGroupId(mGroupId); } - ui->messageTabWidget->setCurrentWidget(msgWidget); + mMessageWidget = msgWidget; } void GxsGroupFrameDialog::groupTreeMiddleButtonClicked(QTreeWidgetItem *item) @@ -885,18 +886,18 @@ void GxsGroupFrameDialog::openGroupInNewTab(const RsGxsGroupId &groupId) void GxsGroupFrameDialog::messageTabCloseRequested(int index) { - QWidget *widget = ui->messageTabWidget->widget(index); - if (!widget) { + if(ui->messageTabWidget->count() == 1) /* Don't close single tab */ return; - } - GxsMessageFrameWidget *msgWidget = dynamic_cast(widget); - if (msgWidget && msgWidget == mMessageWidget) { - /* Don't close single tab */ - return; - } + GxsMessageFrameWidget *msgWidget = dynamic_cast(ui->messageTabWidget->widget(index)); + delete msgWidget ; - delete(widget); + mMessageWidget = currentWidget(); +} + +GxsMessageFrameWidget *GxsGroupFrameDialog::currentWidget() const +{ + return dynamic_cast(ui->messageTabWidget->widget(ui->messageTabWidget->currentIndex())); } void GxsGroupFrameDialog::messageTabChanged(int index) diff --git a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.h b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.h index 902e49087..e1d088a4b 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.h +++ b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.h @@ -192,13 +192,16 @@ protected: bool mCountChildMsgs; // Count unread child messages? private: + GxsMessageFrameWidget *currentWidget() const; + bool mInitialized; bool mInFill; bool mDistSyncAllowed; QString mSettingsName; RsGxsGroupId mGroupId; RsGxsIfaceHelper *mInterface; - GxsMessageFrameWidget *mMessageWidget; + + GxsMessageFrameWidget *mMessageWidget; // current widget QTreeWidgetItem *mYourGroups; QTreeWidgetItem *mSubscribedGroups; diff --git a/retroshare-gui/src/gui/gxs/GxsMessageFrameWidget.h b/retroshare-gui/src/gui/gxs/GxsMessageFrameWidget.h index 9b9a8e34e..36c2f4f67 100644 --- a/retroshare-gui/src/gui/gxs/GxsMessageFrameWidget.h +++ b/retroshare-gui/src/gui/gxs/GxsMessageFrameWidget.h @@ -55,6 +55,7 @@ signals: void groupChanged(QWidget *widget); void waitingChanged(QWidget *widget); void loadComment(const RsGxsGroupId &groupId, const QVector& msg_versions,const RsGxsMessageId &msgId, const QString &title); + void groupDataLoaded(); protected: virtual void setAllMessagesReadDo(bool read, uint32_t &token) = 0; diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.cpp b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.cpp index 7322841cc..5c9c70437 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.cpp +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.cpp @@ -78,6 +78,21 @@ Q_DECLARE_METATYPE(ChannelPostFileInfo) // Delegate used to paint into the table of thumbnails +int ChannelPostDelegate::cellSize(const QFont& font) const +{ + return mZoom*COLUMN_SIZE_FONT_FACTOR_W*QFontMetricsF(font).height(); +} + +void ChannelPostDelegate::zoom(bool zoom_or_unzoom) +{ + if(zoom_or_unzoom) + mZoom *= 1.02; + else + mZoom /= 1.02; + + std::cerr << "zoom factor: " << mZoom << std::endl; +} + void ChannelPostDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const { // prepare @@ -101,11 +116,14 @@ void ChannelPostDelegate::paint(QPainter * painter, const QStyleOptionViewItem & w.render(&pixmap,QPoint(),QRegion(),QWidget::DrawChildren );// draw the widgets, not the background + if(mZoom != 1.0) + pixmap = pixmap.scaled(mZoom*pixmap.size(),Qt::KeepAspectRatio,Qt::SmoothTransformation); + if(IS_MSG_UNREAD(post.mMeta.mMsgStatus) || IS_MSG_NEW(post.mMeta.mMsgStatus)) { QPainter p(&pixmap); QFontMetricsF fm(option.font); - p.drawPixmap(QPoint(6.2*fm.height(),6.9*fm.height()),FilesDefs::getPixmapFromQtResourcePath(STAR_OVERLAY_IMAGE).scaled(7*fm.height(),7*fm.height(),Qt::KeepAspectRatio,Qt::SmoothTransformation)); + p.drawPixmap(mZoom*QPoint(6.2*fm.height(),6.9*fm.height()),FilesDefs::getPixmapFromQtResourcePath(STAR_OVERLAY_IMAGE).scaled(mZoom*7*fm.height(),mZoom*7*fm.height(),Qt::KeepAspectRatio,Qt::SmoothTransformation)); } // debug @@ -128,7 +146,7 @@ QSize ChannelPostDelegate::sizeHint(const QStyleOptionViewItem& option, const QM QFontMetricsF fm(option.font); - return QSize(COLUMN_SIZE_FONT_FACTOR_W*fm.height(),COLUMN_SIZE_FONT_FACTOR_H*fm.height()); + return QSize(mZoom*COLUMN_SIZE_FONT_FACTOR_W*fm.height(),mZoom*COLUMN_SIZE_FONT_FACTOR_H*fm.height()); } QWidget *ChannelPostFilesDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex& index) const @@ -213,11 +231,13 @@ GxsChannelPostsWidgetWithModel::GxsChannelPostsWidgetWithModel(const RsGxsGroupI ui->setupUi(this); ui->postsTree->setModel(mChannelPostsModel = new RsGxsChannelPostsModel()); - ui->postsTree->setItemDelegate(new ChannelPostDelegate()); + ui->postsTree->setItemDelegate(mChannelPostsDelegate = new ChannelPostDelegate()); ui->postsTree->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); // prevents bug on w10, since row size depends on widget width ui->postsTree->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);// more beautiful if we scroll at pixel level ui->postsTree->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); + connect(ui->postsTree,SIGNAL(zoomRequested(bool)),this,SLOT(updateZoomFactor(bool))); + ui->channelPostFiles_TV->setModel(mChannelPostFilesModel = new RsGxsChannelPostFilesModel(this)); ui->channelPostFiles_TV->setItemDelegate(new ChannelPostFilesDelegate()); ui->channelPostFiles_TV->setPlaceholderText(tr("No files in this post, or no post selected")); @@ -251,7 +271,7 @@ GxsChannelPostsWidgetWithModel::GxsChannelPostsWidgetWithModel(const RsGxsGroupI QFontMetricsF fm(font()); for(int i=0;icolumnCount();++i) - ui->postsTree->setColumnWidth(i,COLUMN_SIZE_FONT_FACTOR_W*fm.height()); + ui->postsTree->setColumnWidth(i,mChannelPostsDelegate->cellSize(font())); /* Setup UI helper */ @@ -313,6 +333,23 @@ GxsChannelPostsWidgetWithModel::GxsChannelPostsWidgetWithModel(const RsGxsGroupI }, mEventHandlerId, RsEventType::GXS_CHANNELS ); } +void GxsChannelPostsWidgetWithModel::updateZoomFactor(bool zoom_or_unzoom) +{ + mChannelPostsDelegate->zoom(zoom_or_unzoom); + + for(int i=0;icolumnCount();++i) + ui->postsTree->setColumnWidth(i,mChannelPostsDelegate->cellSize(font())); + + QSize s = ui->postsTree->size(); + + int n_columns = std::max(1,(int)floor(s.width() / (mChannelPostsDelegate->cellSize(font())))); + std::cerr << "nb columns: " << n_columns << std::endl; + + mChannelPostsModel->setNumColumns(n_columns); // forces the update + + ui->postsTree->dataChanged(QModelIndex(),QModelIndex()); +} + void GxsChannelPostsWidgetWithModel::sortColumnPostFiles(int col,Qt::SortOrder so) { std::cerr << "Sorting post files according to col " << col << std::endl; @@ -379,7 +416,7 @@ void GxsChannelPostsWidgetWithModel::editPost() void GxsChannelPostsWidgetWithModel::handlePostsTreeSizeChange(QSize s) { - int n_columns = std::max(1,(int)floor(s.width() / (COLUMN_SIZE_FONT_FACTOR_W*QFontMetricsF(font()).height()))); + int n_columns = std::max(1,(int)floor(s.width() / (mChannelPostsDelegate->cellSize(font())))); std::cerr << "nb columns: " << n_columns << std::endl; if(n_columns != mChannelPostsModel->columnCount()) diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.h b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.h index 86b840fd0..be2ccdf6c 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.h +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.h @@ -60,17 +60,21 @@ class ChannelPostDelegate: public QAbstractItemDelegate Q_OBJECT public: - ChannelPostDelegate(QObject *parent=0) : QAbstractItemDelegate(parent){} + ChannelPostDelegate(QObject *parent=0) : QAbstractItemDelegate(parent), mZoom(1.0){} virtual ~ChannelPostDelegate(){} void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const override; QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const override; + int cellSize(const QFont& font) const; + void zoom(bool zoom_or_unzoom) ; private: static constexpr float IMAGE_MARGIN_FACTOR = 1.0; static constexpr float IMAGE_SIZE_FACTOR_W = 4.0 ; static constexpr float IMAGE_SIZE_FACTOR_H = 6.0 ; static constexpr float IMAGE_ZOOM_FACTOR = 1.0; + + float mZoom; // zoom factor for the whole thumbnail }; class GxsChannelPostsWidgetWithModel: public GxsMessageFrameWidget @@ -142,6 +146,7 @@ private slots: void editPost(); void postContextMenu(const QPoint&); void copyMessageLink(); + void updateZoomFactor(bool zoom_or_unzoom); public slots: void sortColumnFiles(int col,Qt::SortOrder so); @@ -168,6 +173,7 @@ private: RsGxsChannelPostsModel *mChannelPostsModel; RsGxsChannelPostFilesModel *mChannelPostFilesModel; RsGxsChannelPostFilesModel *mChannelFilesModel; + ChannelPostDelegate *mChannelPostsDelegate; RsGxsMessageId mSelectedPost; diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.ui b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.ui index 28687b2df..1f51702a2 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.ui +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.ui @@ -161,7 +161,7 @@ - 0 + 1 @@ -337,7 +337,7 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Description</span></p></body></html>