summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPetr Mrázek <peterix@gmail.com>2014-02-02 14:27:43 +0100
committerPetr Mrázek <peterix@gmail.com>2014-02-02 14:27:43 +0100
commiteb0ed082d877156f543324736cbf4ab85a9ec3f8 (patch)
tree9221bc64b255186f71da331874388e335e57cb7a
parentb2bf50a6d75d32ac483bb53d5c5948b353cd2d16 (diff)
downloadMultiMC-eb0ed082d877156f543324736cbf4ab85a9ec3f8.tar
MultiMC-eb0ed082d877156f543324736cbf4ab85a9ec3f8.tar.gz
MultiMC-eb0ed082d877156f543324736cbf4ab85a9ec3f8.tar.lz
MultiMC-eb0ed082d877156f543324736cbf4ab85a9ec3f8.tar.xz
MultiMC-eb0ed082d877156f543324736cbf4ab85a9ec3f8.zip
Fix group mouse interaction issues
-rw-r--r--Group.cpp39
-rw-r--r--Group.h16
-rw-r--r--GroupView.cpp64
-rw-r--r--GroupView.h23
4 files changed, 109 insertions, 33 deletions
diff --git a/Group.cpp b/Group.cpp
index a62f592b..c92132ca 100644
--- a/Group.cpp
+++ b/Group.cpp
@@ -9,9 +9,9 @@
Group::Group(const QString &text, GroupView *view) : view(view), text(text), collapsed(false)
{
}
+
Group::Group(const Group *other)
- : view(other->view), text(other->text), collapsed(other->collapsed),
- iconRect(other->iconRect), textRect(other->textRect)
+ : view(other->view), text(other->text), collapsed(other->collapsed)
{
}
@@ -27,6 +27,37 @@ void Group::update()
}
}
+Group::HitResults Group::pointIntersect(const QPoint &pos) const
+{
+ Group::HitResults results = Group::NoHit;
+ int y_start = top();
+ int body_start = y_start + headerHeight();
+ int body_end = body_start + contentHeight() + 5; // FIXME: wtf is this 5?
+ int y = pos.y();
+ // int x = pos.x();
+ if(y < y_start)
+ {
+ results = Group::NoHit;
+ }
+ else if(y < body_start)
+ {
+ results = Group::HeaderHit;
+ int collapseSize = headerHeight() - 4;
+
+ // the icon
+ QRect iconRect = QRect(view->m_leftMargin + 2, 2 + y_start, collapseSize, collapseSize);
+ if(iconRect.contains(pos))
+ {
+ results |= Group::CheckboxHit;
+ }
+ }
+ else if (y < body_end)
+ {
+ results |= Group::BodyHit;
+ }
+ return results;
+}
+
void Group::drawHeader(QPainter *painter, const int y)
{
painter->save();
@@ -35,7 +66,7 @@ void Group::drawHeader(QPainter *painter, const int y)
int collapseSize = height;
// the icon
- iconRect = QRect(view->m_rightMargin + 2, 2 + y, collapseSize, collapseSize);
+ QRect iconRect = QRect(view->m_leftMargin + 2, 2 + y, collapseSize, collapseSize);
painter->setPen(QPen(Qt::black, 1));
painter->drawRect(iconRect);
static const int margin = 2;
@@ -50,7 +81,7 @@ void Group::drawHeader(QPainter *painter, const int y)
// the text
int textWidth = painter->fontMetrics().width(text);
- textRect = QRect(iconRect.right() + 4, y, textWidth, headerHeight());
+ QRect textRect = QRect(iconRect.right() + 4, y, textWidth, headerHeight());
painter->setBrush(view->viewOptions().palette.text());
view->style()->drawItemText(painter, textRect, Qt::AlignHCenter | Qt::AlignVCenter,
view->viewport()->palette(), true, text);
diff --git a/Group.h b/Group.h
index 6a8fadeb..51e0470d 100644
--- a/Group.h
+++ b/Group.h
@@ -15,8 +15,6 @@ struct Group
GroupView *view;
QString text;
bool collapsed;
- QRect iconRect;
- QRect textRect;
QVector<int> rowHeights;
int firstRow;
@@ -29,8 +27,22 @@ struct Group
int numRows() const;
int top() const;
+ enum HitResult
+ {
+ NoHit = 0x0,
+ TextHit = 0x1,
+ CheckboxHit = 0x2,
+ HeaderHit = 0x4,
+ BodyHit = 0x8
+ };
+ Q_DECLARE_FLAGS(HitResults, HitResult)
+
+ HitResults pointIntersect (const QPoint &pos) const;
+
QList<QModelIndex> items() const;
int numItems() const;
QModelIndex firstItem() const;
QModelIndex lastItem() const;
};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(Group::HitResults)
diff --git a/GroupView.cpp b/GroupView.cpp
index 50d19f52..1f0a51e7 100644
--- a/GroupView.cpp
+++ b/GroupView.cpp
@@ -36,7 +36,7 @@ GroupView::GroupView(QWidget *parent)
// setWordWrap(true);
// setDragDropMode(QListView::InternalMove);
setAcceptDrops(true);
- // setSpacing(10);
+ m_spacing = 5;
}
GroupView::~GroupView()
@@ -145,31 +145,31 @@ Group *GroupView::category(const QModelIndex &index) const
Group *GroupView::category(const QString &cat) const
{
- for (int i = 0; i < m_categories.size(); ++i)
+ for (auto group : m_categories)
{
- if (m_categories.at(i)->text == cat)
+ if (group->text == cat)
{
- return m_categories.at(i);
+ return group;
}
}
- return 0;
+ return nullptr;
}
Group *GroupView::categoryAt(const QPoint &pos) const
{
- for (int i = 0; i < m_categories.size(); ++i)
+ for (auto group : m_categories)
{
- if (m_categories.at(i)->iconRect.contains(pos))
+ if(group->pointIntersect(pos) & Group::CheckboxHit)
{
- return m_categories.at(i);
+ return group;
}
}
- return 0;
+ return nullptr;
}
int GroupView::itemsPerRow() const
{
- return qFloor((qreal)(contentWidth()) / (qreal)(itemWidth() + /* spacing */ 10));
+ return qFloor((qreal)(contentWidth()) / (qreal)(itemWidth() + m_spacing));
}
int GroupView::contentWidth() const
@@ -261,7 +261,7 @@ void GroupView::mousePressEvent(QMouseEvent *event)
m_pressedIndex = index;
m_pressedAlreadySelected = selectionModel()->isSelected(m_pressedIndex);
- QItemSelectionModel::SelectionFlags command = selectionCommand(index, event);
+ QItemSelectionModel::SelectionFlags selection_flags = selectionCommand(index, event);
m_pressedPosition = pos;
m_pressedCategory = categoryAt(m_pressedPosition);
@@ -428,9 +428,8 @@ void GroupView::mouseDoubleClickEvent(QMouseEvent *event)
void GroupView::paintEvent(QPaintEvent *event)
{
QPainter painter(this->viewport());
- painter.translate(-offset());
- int y = 0;
+ int y = -verticalOffset();
for (int i = 0; i < m_categories.size(); ++i)
{
Group *category = m_categories.at(i);
@@ -502,7 +501,7 @@ void GroupView::resizeEvent(QResizeEvent *event)
// if (m_categoryEditor)
// {
// m_categoryEditor->resize(qMax(contentWidth() / 2,
- //m_editedCategory->textRect.width()),
+ // m_editedCategory->textRect.width()),
// m_categoryEditor->height());
// }
@@ -619,6 +618,11 @@ void GroupView::startDrag(Qt::DropActions supportedActions)
QRect GroupView::visualRect(const QModelIndex &index) const
{
+ return geometryRect(index).translated(-offset());
+}
+
+QRect GroupView::geometryRect(const QModelIndex &index) const
+{
if (!index.isValid() || isIndexHidden(index) || index.column() > 0)
{
return QRect();
@@ -627,15 +631,16 @@ QRect GroupView::visualRect(const QModelIndex &index) const
const Group *cat = category(index);
QPair<int, int> pos = categoryInternalPosition(index);
int x = pos.first;
- int y = pos.second;
+ // int y = pos.second;
QRect out;
out.setTop(cat->top() + cat->headerHeight() + 5 + categoryInternalRowTop(index));
- out.setLeft(/*spacing*/ 10 + x * itemWidth() + x * /*spacing()*/ 10);
+ out.setLeft(m_spacing + x * (itemWidth() + m_spacing));
out.setSize(itemDelegate()->sizeHint(viewOptions(), index));
return out;
}
+
/*
void CategorizedView::startCategoryEditor(Category *category)
{
@@ -680,7 +685,7 @@ QModelIndex GroupView::indexAt(const QPoint &point) const
for (int i = 0; i < model()->rowCount(); ++i)
{
QModelIndex index = model()->index(i, 0);
- if (visualRect(index).contains(point))
+ if (geometryRect(index).contains(point))
{
return index;
}
@@ -694,7 +699,7 @@ void GroupView::setSelection(const QRect &rect,
for (int i = 0; i < model()->rowCount(); ++i)
{
QModelIndex index = model()->index(i, 0);
- if (visualRect(index).intersects(rect))
+ if (geometryRect(index).intersects(rect))
{
selectionModel()->select(index, commands);
}
@@ -734,7 +739,7 @@ QList<QPair<QRect, QModelIndex>> GroupView::draggablePaintPairs(const QModelInde
for (int i = 0; i < indices.count(); ++i)
{
const QModelIndex &index = indices.at(i);
- const QRect current = visualRect(index);
+ const QRect current = geometryRect(index);
if (current.intersects(viewportRect))
{
ret += qMakePair(current, index);
@@ -857,3 +862,24 @@ QPoint GroupView::offset() const
{
return QPoint(horizontalOffset(), verticalOffset());
}
+
+QRegion GroupView::visualRegionForSelection(const QItemSelection &selection) const
+{
+ QRegion region;
+ for (auto &range : selection)
+ {
+ int start_row = range.top();
+ int end_row = range.bottom();
+ for (int row = start_row; row <= end_row; ++row)
+ {
+ int start_column = range.left();
+ int end_column = range.right();
+ for (int column = start_column; column <= end_column; ++column)
+ {
+ QModelIndex index = model()->index(row, column, rootIndex());
+ region += visualRect(index); // OK
+ }
+ }
+ }
+ return region;
+}
diff --git a/GroupView.h b/GroupView.h
index bf911794..2c60f0e9 100644
--- a/GroupView.h
+++ b/GroupView.h
@@ -2,6 +2,7 @@
#include <QListView>
#include <QLineEdit>
+#include <QScrollBar>
struct CategorizedViewRoles
{
@@ -23,7 +24,8 @@ public:
GroupView(QWidget *parent = 0);
~GroupView();
- virtual QRect visualRect(const QModelIndex &index) const;
+ virtual QRect geometryRect(const QModelIndex &index) const;
+ virtual QRect visualRect(const QModelIndex &index) const override;
QModelIndex indexAt(const QPoint &point) const;
void setSelection(const QRect &rect,
const QItemSelectionModel::SelectionFlags commands) override;
@@ -34,12 +36,18 @@ public:
virtual int horizontalOffset() const override
{
- return 0;
+ return horizontalScrollBar()->value();
}
virtual int verticalOffset() const override
{
- return 0;
+ return verticalScrollBar()->value();
+ }
+
+ virtual void scrollContentsBy(int dx, int dy) override
+ {
+ scrollDirtyRegion(dx, dy);
+ viewport()->scroll(dx, dy);
}
virtual void scrollTo(const QModelIndex &index, ScrollHint hint = EnsureVisible) override
@@ -53,10 +61,7 @@ public:
return QModelIndex();
}
- virtual QRegion visualRegionForSelection(const QItemSelection &) const override
- {
- return QRegion();
- }
+ virtual QRegion visualRegionForSelection(const QItemSelection &selection) const override;
/*
* End of BS
@@ -116,14 +121,16 @@ private:
private slots:
void endCategoryEditor();*/
-private:
+private: /* variables */
QPoint m_pressedPosition;
QPersistentModelIndex m_pressedIndex;
bool m_pressedAlreadySelected;
Group *m_pressedCategory;
QItemSelectionModel::SelectionFlag m_ctrlDragSelectionFlag;
QPoint m_lastDragPosition;
+ int m_spacing = 5;
+private: /* methods */
QPair<int, int> categoryInternalPosition(const QModelIndex &index) const;
int categoryInternalRowTop(const QModelIndex &index) const;
int itemHeightForCategoryRow(const Group *category, const int internalRow) const;