added zoom of thumbnails on control+wheel

This commit is contained in:
csoler 2020-06-23 20:24:14 +02:00
parent 97ad766863
commit d39b09c5bc
No known key found for this signature in database
GPG Key ID: 7BCA522266C0804C
8 changed files with 91 additions and 33 deletions

View File

@ -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. 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) void RSTreeView::mouseMoveEvent(QMouseEvent *e)
{ {
QModelIndex idx = indexAt(e->pos()); QModelIndex idx = indexAt(e->pos());

View File

@ -40,9 +40,11 @@ public:
signals: signals:
void sizeChanged(QSize); void sizeChanged(QSize);
void zoomRequested(bool zoom_or_unzoom);
protected: protected:
virtual void mouseMoveEvent(QMouseEvent *e) override; // overriding so as to manage auto-selection 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 resizeEvent(QResizeEvent *e) override;
virtual void paintEvent(QPaintEvent *event) override; virtual void paintEvent(QPaintEvent *event) override;

View File

@ -390,6 +390,7 @@ static uint32_t checkDelay(uint32_t time_in_secs)
return 365 * 86400; return 365 * 86400;
} }
void GxsGroupFrameDialog::groupTreeCustomPopupMenu(QPoint point) void GxsGroupFrameDialog::groupTreeCustomPopupMenu(QPoint point)
{ {
// First separately handle the case of search top level items // First separately handle the case of search top level items
@ -433,11 +434,12 @@ void GxsGroupFrameDialog::groupTreeCustomPopupMenu(QPoint point)
QAction *action; QAction *action;
#ifdef TODO #ifdef TODO
if (mMessageWidget) { if (mMessageWidget)
action = contextMnu.addAction(QIcon(IMAGE_TABNEW), tr("Open in new tab"), this, SLOT(openInNewTab())); {
if (mGroupId.isNull() || messageWidget(mGroupId, true)) { 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); action->setEnabled(false);
}
} }
#endif #endif
@ -841,20 +843,19 @@ void GxsGroupFrameDialog::changedCurrentGroup(const QString& groupId)
/* search exisiting tab */ /* search exisiting tab */
GxsMessageFrameWidget *msgWidget = messageWidget(mGroupId, true); 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) msgWidget = currentWidget();
{ msgWidget->setGroupId(mGroupId);
/* not found, use standard tab */
msgWidget = mMessageWidget;
msgWidget->setGroupId(mGroupId);
} else {
/* create new tab */
msgWidget = createMessageWidget(mGroupId);
}
} }
ui->messageTabWidget->setCurrentWidget(msgWidget); mMessageWidget = msgWidget;
} }
void GxsGroupFrameDialog::groupTreeMiddleButtonClicked(QTreeWidgetItem *item) void GxsGroupFrameDialog::groupTreeMiddleButtonClicked(QTreeWidgetItem *item)
@ -885,18 +886,18 @@ void GxsGroupFrameDialog::openGroupInNewTab(const RsGxsGroupId &groupId)
void GxsGroupFrameDialog::messageTabCloseRequested(int index) void GxsGroupFrameDialog::messageTabCloseRequested(int index)
{ {
QWidget *widget = ui->messageTabWidget->widget(index); if(ui->messageTabWidget->count() == 1) /* Don't close single tab */
if (!widget) {
return; return;
}
GxsMessageFrameWidget *msgWidget = dynamic_cast<GxsMessageFrameWidget*>(widget); GxsMessageFrameWidget *msgWidget = dynamic_cast<GxsMessageFrameWidget*>(ui->messageTabWidget->widget(index));
if (msgWidget && msgWidget == mMessageWidget) { delete msgWidget ;
/* Don't close single tab */
return;
}
delete(widget); mMessageWidget = currentWidget();
}
GxsMessageFrameWidget *GxsGroupFrameDialog::currentWidget() const
{
return dynamic_cast<GxsMessageFrameWidget*>(ui->messageTabWidget->widget(ui->messageTabWidget->currentIndex()));
} }
void GxsGroupFrameDialog::messageTabChanged(int index) void GxsGroupFrameDialog::messageTabChanged(int index)

View File

@ -192,13 +192,16 @@ protected:
bool mCountChildMsgs; // Count unread child messages? bool mCountChildMsgs; // Count unread child messages?
private: private:
GxsMessageFrameWidget *currentWidget() const;
bool mInitialized; bool mInitialized;
bool mInFill; bool mInFill;
bool mDistSyncAllowed; bool mDistSyncAllowed;
QString mSettingsName; QString mSettingsName;
RsGxsGroupId mGroupId; RsGxsGroupId mGroupId;
RsGxsIfaceHelper *mInterface; RsGxsIfaceHelper *mInterface;
GxsMessageFrameWidget *mMessageWidget;
GxsMessageFrameWidget *mMessageWidget; // current widget
QTreeWidgetItem *mYourGroups; QTreeWidgetItem *mYourGroups;
QTreeWidgetItem *mSubscribedGroups; QTreeWidgetItem *mSubscribedGroups;

View File

@ -55,6 +55,7 @@ signals:
void groupChanged(QWidget *widget); void groupChanged(QWidget *widget);
void waitingChanged(QWidget *widget); void waitingChanged(QWidget *widget);
void loadComment(const RsGxsGroupId &groupId, const QVector<RsGxsMessageId>& msg_versions,const RsGxsMessageId &msgId, const QString &title); void loadComment(const RsGxsGroupId &groupId, const QVector<RsGxsMessageId>& msg_versions,const RsGxsMessageId &msgId, const QString &title);
void groupDataLoaded();
protected: protected:
virtual void setAllMessagesReadDo(bool read, uint32_t &token) = 0; virtual void setAllMessagesReadDo(bool read, uint32_t &token) = 0;

View File

@ -78,6 +78,21 @@ Q_DECLARE_METATYPE(ChannelPostFileInfo)
// Delegate used to paint into the table of thumbnails // 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 void ChannelPostDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const
{ {
// prepare // 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 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)) if(IS_MSG_UNREAD(post.mMeta.mMsgStatus) || IS_MSG_NEW(post.mMeta.mMsgStatus))
{ {
QPainter p(&pixmap); QPainter p(&pixmap);
QFontMetricsF fm(option.font); 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 // debug
@ -128,7 +146,7 @@ QSize ChannelPostDelegate::sizeHint(const QStyleOptionViewItem& option, const QM
QFontMetricsF fm(option.font); 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 QWidget *ChannelPostFilesDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex& index) const
@ -213,11 +231,13 @@ GxsChannelPostsWidgetWithModel::GxsChannelPostsWidgetWithModel(const RsGxsGroupI
ui->setupUi(this); ui->setupUi(this);
ui->postsTree->setModel(mChannelPostsModel = new RsGxsChannelPostsModel()); 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->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->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);// more beautiful if we scroll at pixel level
ui->postsTree->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); 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->setModel(mChannelPostFilesModel = new RsGxsChannelPostFilesModel(this));
ui->channelPostFiles_TV->setItemDelegate(new ChannelPostFilesDelegate()); ui->channelPostFiles_TV->setItemDelegate(new ChannelPostFilesDelegate());
ui->channelPostFiles_TV->setPlaceholderText(tr("No files in this post, or no post selected")); 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()); QFontMetricsF fm(font());
for(int i=0;i<mChannelPostsModel->columnCount();++i) for(int i=0;i<mChannelPostsModel->columnCount();++i)
ui->postsTree->setColumnWidth(i,COLUMN_SIZE_FONT_FACTOR_W*fm.height()); ui->postsTree->setColumnWidth(i,mChannelPostsDelegate->cellSize(font()));
/* Setup UI helper */ /* Setup UI helper */
@ -313,6 +333,23 @@ GxsChannelPostsWidgetWithModel::GxsChannelPostsWidgetWithModel(const RsGxsGroupI
}, mEventHandlerId, RsEventType::GXS_CHANNELS ); }, mEventHandlerId, RsEventType::GXS_CHANNELS );
} }
void GxsChannelPostsWidgetWithModel::updateZoomFactor(bool zoom_or_unzoom)
{
mChannelPostsDelegate->zoom(zoom_or_unzoom);
for(int i=0;i<mChannelPostsModel->columnCount();++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) void GxsChannelPostsWidgetWithModel::sortColumnPostFiles(int col,Qt::SortOrder so)
{ {
std::cerr << "Sorting post files according to col " << col << std::endl; std::cerr << "Sorting post files according to col " << col << std::endl;
@ -379,7 +416,7 @@ void GxsChannelPostsWidgetWithModel::editPost()
void GxsChannelPostsWidgetWithModel::handlePostsTreeSizeChange(QSize s) 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; std::cerr << "nb columns: " << n_columns << std::endl;
if(n_columns != mChannelPostsModel->columnCount()) if(n_columns != mChannelPostsModel->columnCount())

View File

@ -60,17 +60,21 @@ class ChannelPostDelegate: public QAbstractItemDelegate
Q_OBJECT Q_OBJECT
public: public:
ChannelPostDelegate(QObject *parent=0) : QAbstractItemDelegate(parent){} ChannelPostDelegate(QObject *parent=0) : QAbstractItemDelegate(parent), mZoom(1.0){}
virtual ~ChannelPostDelegate(){} virtual ~ChannelPostDelegate(){}
void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const override; void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const override;
QSize sizeHint(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: private:
static constexpr float IMAGE_MARGIN_FACTOR = 1.0; static constexpr float IMAGE_MARGIN_FACTOR = 1.0;
static constexpr float IMAGE_SIZE_FACTOR_W = 4.0 ; static constexpr float IMAGE_SIZE_FACTOR_W = 4.0 ;
static constexpr float IMAGE_SIZE_FACTOR_H = 6.0 ; static constexpr float IMAGE_SIZE_FACTOR_H = 6.0 ;
static constexpr float IMAGE_ZOOM_FACTOR = 1.0; static constexpr float IMAGE_ZOOM_FACTOR = 1.0;
float mZoom; // zoom factor for the whole thumbnail
}; };
class GxsChannelPostsWidgetWithModel: public GxsMessageFrameWidget class GxsChannelPostsWidgetWithModel: public GxsMessageFrameWidget
@ -142,6 +146,7 @@ private slots:
void editPost(); void editPost();
void postContextMenu(const QPoint&); void postContextMenu(const QPoint&);
void copyMessageLink(); void copyMessageLink();
void updateZoomFactor(bool zoom_or_unzoom);
public slots: public slots:
void sortColumnFiles(int col,Qt::SortOrder so); void sortColumnFiles(int col,Qt::SortOrder so);
@ -168,6 +173,7 @@ private:
RsGxsChannelPostsModel *mChannelPostsModel; RsGxsChannelPostsModel *mChannelPostsModel;
RsGxsChannelPostFilesModel *mChannelPostFilesModel; RsGxsChannelPostFilesModel *mChannelPostFilesModel;
RsGxsChannelPostFilesModel *mChannelFilesModel; RsGxsChannelPostFilesModel *mChannelFilesModel;
ChannelPostDelegate *mChannelPostsDelegate;
RsGxsMessageId mSelectedPost; RsGxsMessageId mSelectedPost;

View File

@ -161,7 +161,7 @@
<item> <item>
<widget class="QTabWidget" name="channel_TW"> <widget class="QTabWidget" name="channel_TW">
<property name="currentIndex"> <property name="currentIndex">
<number>0</number> <number>1</number>
</property> </property>
<widget class="QWidget" name="tab_3"> <widget class="QWidget" name="tab_3">
<attribute name="title"> <attribute name="title">
@ -337,7 +337,7 @@
<string notr="true">&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt; <string notr="true">&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt; &lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; } p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;&quot;&gt; &lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-size:8pt;&quot;&gt;Description&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-size:8pt;&quot;&gt;Description&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="textInteractionFlags"> <property name="textInteractionFlags">