aboutsummaryrefslogtreecommitdiff
path: root/qtmips_gui/statictable.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'qtmips_gui/statictable.cpp')
-rw-r--r--qtmips_gui/statictable.cpp255
1 files changed, 255 insertions, 0 deletions
diff --git a/qtmips_gui/statictable.cpp b/qtmips_gui/statictable.cpp
new file mode 100644
index 0000000..8686847
--- /dev/null
+++ b/qtmips_gui/statictable.cpp
@@ -0,0 +1,255 @@
+#include "statictable.h"
+#include <QPainter>
+#include <qtmipsexception.h>
+
+#include <iostream>
+using namespace std;
+
+StaticTableLayout::StaticTableLayout(QWidget *parent, int margin, int horizontal_big_spacing, int horizontal_small_spacing, int vertical_spacing) : QLayout(parent) {
+ setContentsMargins(margin, margin, margin, margin);
+ bhspace = horizontal_big_spacing;
+ shspace = horizontal_small_spacing;
+ vspace = vertical_spacing;
+ setSizeConstraint(QLayout::SetMinAndMaxSize);
+}
+
+StaticTableLayout::~StaticTableLayout() {
+ for (int i = 0; i < items.size(); i++) {
+ for (int y = 0; y < items[i].size(); y++)
+ delete items[i][y];
+ }
+}
+
+Qt::Orientations StaticTableLayout::expandingDirections() const {
+ return Qt::Horizontal;
+}
+
+bool StaticTableLayout::hasHeightForWidth() const {
+ return true;
+}
+
+int StaticTableLayout::heightForWidth(int w) const {
+ // TODO cache value
+ return layout_height(w);
+}
+
+QSize StaticTableLayout::minimumSize() const {
+ QSize s;
+ for (int i = 0; i < items.size(); i++) {
+ QSize ss;
+ for (int y = 0; y < items[i].size(); y++) {
+ ss = s.expandedTo(items[i][y]->minimumSize() + QSize(shspace, 0));
+ }
+ s = s.expandedTo(ss - QSize(shspace, 0));
+ }
+ s += QSize(2*margin(), 2*margin());
+ return s;
+}
+
+void StaticTableLayout::setGeometry(const QRect &rect) {
+ QLayout::setGeometry(rect);
+ do_layout(rect);
+}
+
+QSize StaticTableLayout::sizeHint() const {
+ return minimumSize();
+}
+
+void StaticTableLayout::addItem(QLayoutItem *item __attribute__((unused))) {
+ // Just implement it but it does nothing
+}
+
+QLayoutItem *StaticTableLayout::itemAt(int index __attribute__((unused))) const {
+ return nullptr; // This is just dummy implementation to satisfy reimplementation
+}
+
+QLayoutItem *StaticTableLayout::takeAt(int index __attribute__((unused))) {
+ return nullptr; // This is just dummy implementation to satisfy reimplementation
+}
+
+int StaticTableLayout::count() const {
+ return items.size();
+}
+
+void StaticTableLayout::addRow(QList<QWidget*> w) {
+ QVector<QLayoutItem*> v;
+ for (int i = 0; i < w.size(); i++) {
+ addChildWidget(w[i]);
+ v.append(new QWidgetItem(w[i]));
+ }
+
+ items.append(v);
+}
+
+void StaticTableLayout::itemRect(QRect &rect, QVector<int> &separators, int i) {
+ separators.clear();
+
+ int row = i / columns();
+ int col = i % columns();
+
+ int left, top, right, bottom;
+ getContentsMargins(&left, &top, &right, &bottom);
+
+ int x = left;
+ for (int s = 0; s < col; s++) {
+ for (int t = 0; t < row_widths[s].size(); t++)
+ x += row_widths[s][t] + shspace;
+ x += bhspace - shspace;
+ }
+ if (col > 0) // otherwise we are on left edge and there was no previous column so no big space
+ x -= bhspace/2;
+ int y = top + (row * (row_height + vspace));
+
+
+ int width = 0;
+ for (int t = 0; t < row_widths[col].size(); t++) {
+ width += row_widths[col][t] + shspace;
+ separators.append(width - shspace/2);
+ }
+ if (col <= 0)
+ width -= bhspace/2;
+
+ rect = QRect(x, y - vspace/2, width - shspace + bhspace, row_height + vspace);
+ separators.removeLast(); // drop last separator as that one we don't want to see
+}
+
+int StaticTableLayout::columns() {
+ return row_widths.size();
+}
+
+int StaticTableLayout::layout_count_approx(const QRect &rect) const {
+ if (items.size() <= 0)
+ return 1;
+ int w = 0;
+ for (int i = 0; i < items[0].size(); i++)
+ w += items[0][i]->sizeHint().width() + shspace;
+ w -= shspace; // subtract lastest spacing
+ int width = rect.right() / w; // Note: this always rounds down so this always founds maximal possible count
+ return width <= 0 ? 1 : width; // We have to fit at least one column
+}
+
+int StaticTableLayout::layout_size(int &row_h, QList<QList<int>> &row_w, int count) const {
+ row_h = 0;
+ row_w.clear();
+ int col = 0;
+ for (int i = 0; i < items.size(); i++) {
+ if (row_w.size() <= col)
+ row_w.append(QList<int>());
+ for (int y = 0; y < items[i].size(); y++) {
+ QSize s = items[i][y]->sizeHint();
+ row_h = qMax(row_h, s.height());
+ if (row_w[col].size() <= y)
+ row_w[col].append(0);
+ row_w[col][y] = qMax(row_w[col][y], s.width());
+ }
+ if (++col >= count)
+ col = 0;
+ }
+ SANITY_ASSERT(row_w.size() <= count, "We should end up with maximum of count columns");
+
+ int w = 0;
+ for (int i = 0; i < row_w.size(); i++) {
+ for (int y = 0; y < row_w[i].size(); y++)
+ w += row_w[i][y] + shspace;
+ w += bhspace - shspace; // subtract latest small spacing and add big spacing
+ }
+ w -= bhspace; // subtract latest big spacing
+ return w;
+}
+
+void StaticTableLayout::layout_parms(QRect &rect, int &row_h, QList<QList<int>> &row_w, int &count) const {
+ int left, top, right, bottom;
+ getContentsMargins(&left, &top, &right, &bottom);
+ rect = rect.adjusted(left, top, -right, -bottom);
+
+ // Firt let's do orientation count only on first line
+ count = layout_count_approx(rect);
+ if (layout_size(row_h, row_w, count) > rect.right()) {
+ // Not using orientation count go down if we can't fit (if we can then just be happy with what we have)
+ do {
+ if (count <= 1)
+ // TODO meaby warning?
+ break; // We can't fit it but ignore that.
+ count--;
+ } while (layout_size(row_h, row_w, count) <= rect.width());
+ }
+}
+
+void StaticTableLayout::do_layout(const QRect &rect) {
+ int row_h;
+ QList<QList<int>> row_w;
+ int count;
+
+ QRect reff(rect);
+ layout_parms(reff, row_h, row_w, count);
+
+ int col = 0;
+ int x = reff.x(), y = reff.y();
+ for (int i = 0; i < items.size(); i++) {
+ for (int ii = 0; ii < items[i].size(); ii++) {
+ items[i][ii]->setGeometry(QRect(x, y, row_w[col][ii], row_h));
+ x += row_w[col][ii] + shspace;
+ }
+ x += bhspace - shspace;
+ if (++col >= count) {
+ col = 0;
+ x = reff.x();
+ y += row_h + vspace;
+ }
+ }
+ row_height = row_h;
+ row_widths = row_w;
+}
+
+int StaticTableLayout::layout_height(int width) const {
+ QRect reff(0, 0, width, 0);
+ int row_h;
+ QList<QList<int>> row_w;
+ int count;
+ layout_parms(reff, row_h, row_w, count);
+
+ return (row_h + vspace) * (items.size() / count);
+}
+
+StaticTable::StaticTable(QWidget *parent) : QWidget(parent), layout(this) {
+ setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
+}
+
+void StaticTable::addRow(QList<QWidget*> w) {
+ layout.addRow(w);
+}
+
+void StaticTable::paintEvent(QPaintEvent*) {
+ QPainter p(this);
+ p.setPen(QPen(QColor(200, 200, 200)));
+
+ QRect rect;
+ QVector<int> separators;
+ for (int i = 0; i < layout.count(); i++) {
+ int row = i / layout.columns();
+ int col = i % layout.columns();
+
+ if ((col % 2) == (row % 2))
+ p.setBrush(QBrush(QColor(255, 255, 255)));
+ else
+ p.setBrush(QBrush(QColor(230, 230, 230)));
+
+ layout.itemRect(rect, separators, i);
+
+ int x = rect.left(); // just to store x
+ if (col <= 0) // this is left most row
+ rect.setLeft(-2);
+ if (col >= (layout.columns() - 1))
+ rect.setRight(width());
+ if (row <= 0)
+ rect.setTop(-2);;
+
+ p.drawRect(rect);
+
+ for (int s = 0; s < separators.size(); s++) {
+ int sep_x = x + separators[s];
+ p.drawLine(sep_x, rect.top(), sep_x, rect.bottom());
+ }
+ }
+
+}