[rkward/work/optionset_experiments] rkward: Incomplete attempt at implementing tabslide
Thomas Friedrichsmeier
thomas.friedrichsmeier at ruhr-uni-bochum.de
Fri Oct 23 19:08:27 UTC 2015
Git commit 4302f657ea9c70c0f986f338af81a43c200af9c7 by Thomas Friedrichsmeier.
Committed on 01/10/2015 at 19:09.
Pushed by tfry into branch 'work/optionset_experiments'.
Incomplete attempt at implementing tabslide
M +1 -0 rkward/misc/CMakeLists.txt
M +95 -0 rkward/misc/rktabslide.cpp
M +25 -37 rkward/misc/rktabslide.h
M +7 -4 rkward/plugin/rkoptionset.cpp
M +2 -0 rkward/plugin/rkoptionset.h
http://commits.kde.org/rkward/4302f657ea9c70c0f986f338af81a43c200af9c7
diff --git a/rkward/misc/CMakeLists.txt b/rkward/misc/CMakeLists.txt
index 285b90b..35988bc 100644
--- a/rkward/misc/CMakeLists.txt
+++ b/rkward/misc/CMakeLists.txt
@@ -26,6 +26,7 @@ SET(misc_STAT_SRCS
rkmessagecatalog.cpp
rkdbusapi.cpp
rkfindbar.cpp
+ rktabslide.cpp
)
QT4_AUTOMOC(${misc_STAT_SRCS})
diff --git a/rkward/misc/rktabslide.cpp b/rkward/misc/rktabslide.cpp
index ae2ce5e..5d03824 100644
--- a/rkward/misc/rktabslide.cpp
+++ b/rkward/misc/rktabslide.cpp
@@ -17,3 +17,98 @@
#include "rktabslide.h"
+#include <QSplitter>
+#include <QVBoxLayout>
+#include <QPainter>
+#include <kvbox.h>
+
+#include "../debug.h"
+
+RKTabSlide::RKTabSlide (QWidget* parent) : QWidget (parent) {
+ RK_TRACE (MISC);
+
+ new QVBoxLayout (this);
+ splitter = new QSplitter (this);
+ tab_bar = new RKTabSlideBar (0);
+ splitter->addWidget (tab_bar);
+ splitter->setCollapsible (0, false);
+ content = new KVBox;
+ splitter->addWidget (content);
+ layout ()->addWidget (splitter);
+
+ last_content_width = -1;
+
+ connect (tab_bar, SIGNAL (activated(int)), this, SLOT (activate(int)));
+}
+
+void RKTabSlide::activate (int index) {
+ RK_TRACE (MISC);
+
+ if (index < 0) {
+ int s = splitter->sizes ().value (1, 0);
+ if (s > 0) last_content_width = s;
+ splitter->setSizes (QList<int> () << width () << 0);
+ tab_bar->setWide (true);
+ } else {
+ tab_bar->setWide (false);
+ int s = last_content_width;
+ if (s <= 0) {
+ s = content->minimumWidth ();
+ }
+ splitter->setSizes (QList<int> () << width () - s << s);
+ }
+}
+
+RKTabSlideBar::RKTabSlideBar (QWidget* parent) : QTreeView (parent) {
+ RK_TRACE (MISC);
+
+ buttons = 0;
+ setWide (false);
+
+ QStyleOptionTabV3 toption;
+ toption.shape = QTabBar::RoundedWest;
+ tab_vspace = style()->pixelMetric (QStyle::PM_TabBarTabVSpace, &toption);
+ tab_hspace = style()->pixelMetric (QStyle::PM_TabBarTabVSpace, &toption);
+ tab_height = fontMetrics ().height () + tab_vspace;
+
+ setItemsExpandable (false);
+ setRootIsDecorated (false);
+ setSelectionBehavior (QAbstractItemView::SelectRows);
+ setSelectionMode (QAbstractItemView::SingleSelection);
+}
+#error Gaaaaah. Perhaps base on QListView + QItemDelegate w/o clipping, instead?
+void RKTabSlideBar::drawRow (QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {
+// RK_TRACE (MISC);
+
+ QStyleOptionTabV3 toption;
+ toption.initFrom (this);
+ toption.shape = QTabBar::RoundedWest;
+ toption.rect = option.rect;
+ toption.rect.moveTop (option.rect.y () + dirtyRegionOffset ().y () + tab_vspace);
+ toption.rect.moveLeft (option.rect.x () + dirtyRegionOffset ().x () + tab_hspace);
+ toption.text = index.data ().toString ();
+
+ int current_row = currentIndex ().row ();
+ if (current_row > 0) {
+ int paint_row = index.row ();
+ if (current_row == paint_row) toption.state |= QStyle::State_Selected;
+ else if (current_row == (paint_row - 1)) toption.selectedPosition = QStyleOptionTabV3::PreviousIsSelected;
+ else if (current_row == (paint_row + 1)) toption.selectedPosition = QStyleOptionTabV3::NextIsSelected;
+ }
+
+ style ()->drawControl (QStyle::CE_TabBarTabShape, &toption, painter);
+ toption.shape = QTabBar::RoundedNorth;
+ style ()->drawControl (QStyle::CE_TabBarTabLabel, &toption, painter);
+}
+
+void RKTabSlideBar::setWide (bool wide_format) {
+ RK_TRACE (MISC);
+
+ is_wide = wide_format;
+ setHorizontalScrollBarPolicy (is_wide ? Qt::ScrollBarAsNeeded : Qt::ScrollBarAlwaysOff);
+ // TODO: redraw
+}
+
+
+// KF5 TODO: remove:
+#include "rktabslide.moc"
diff --git a/rkward/misc/rktabslide.h b/rkward/misc/rktabslide.h
index 913dfc0..52e765c 100644
--- a/rkward/misc/rktabslide.h
+++ b/rkward/misc/rktabslide.h
@@ -20,65 +20,53 @@
#include <QWidget>
#include <QScrollArea>
-#include <QPushButton>
+#include <QTreeView>
+class QSplitter;
class RKTabSlideBar;
class RKTabSlide : public QWidget {
+ Q_OBJECT
+public:
+ RKTabSlide (QWidget *parent);
+ RKTabSlideBar *tabBar () const { return tab_bar; };
+ QWidget *contentArea () const { return content; };
+public slots:
+ void activate (int index);
private:
RKTabSlideBar *tab_bar;
QSplitter *splitter;
QWidget *content;
+ int last_content_width;
};
-class RKTabButton;
-class RKTabSlideBar : public QScrollArea {
+class RKTabSlideBar : public QTreeView { // basing on QTreeView, rather than QTableView, as the former is already designed for drawing row by row, rather than cell by cell
Q_OBJECT
public:
RKTabSlideBar (QWidget* parent);
- void insertTab (int index, const QString &short_label, const QString &long_label, const QString &tip);
- void changeTab (int index, const QString &short_label, const QString &long_label, const QString &tip);
- void removeTab (int index);
-signals:
- void deleteClicked (int index);
- void insertClicked (int index);
- void activated (int index);
-private:
-friend class RKTabButton;
- void deleteClicked (RKTabButton*);
- void insertClicked (RKTabButton*);
- void editClicked (RKTabButton*);
- int currentindex;
- QList<RKTabButton*> tabs;
- QWidget* vbox;
- QVBoxLayout *vlayout;
-};
-
-class RKTabButton : public QPushButton {
- Q_OBJECT
-private:
-friend class RKTabSlideBar;
- RKTabButton (QWidget *parent, RKTabSlideBar *bar);
-
- void change (const QString &short_label, const QString &long_label);
- void setWide (bool make_wide);
enum InternalButtons {
Delete,
Insert,
Edit
};
void setInternalButtons (int buttons);
+
+ void setWide (bool wide_format);
+signals:
+ void deleteClicked (int index);
+ void insertClicked (int index);
+ void activated (int index);
protected:
- void paintEvent (QPaintEvent *event);
+ void drawRow (QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; // re-implemented from QTreeView
+ int sizeHintForRow (int) const { return tab_height; }; // re-implemented from QAbstractItemView: Rows have uniform size. TODO: Guess we also need a QItemDelegate implementing sizeHint().
private:
- QString short_label;
- QString long_label;
-private slots:
- void buttonClicked (); // To relay clicked()-signal without additional mapper
- int index;
+ int currentindex;
+ bool is_wide;
+ int buttons;
+ int tab_height;
+ int tab_vspace;
+ int tab_hspace;
};
#endif
-
-
diff --git a/rkward/plugin/rkoptionset.cpp b/rkward/plugin/rkoptionset.cpp
index 6a38df2..a9b367f 100644
--- a/rkward/plugin/rkoptionset.cpp
+++ b/rkward/plugin/rkoptionset.cpp
@@ -29,6 +29,7 @@
#include "rkstandardcomponent.h"
#include "../misc/rkcommonfunctions.h"
+#include "../misc/rktabslide.h"
#include "../misc/rkstandardicons.h"
#include "../misc/xmlhelper.h"
@@ -47,7 +48,7 @@ RKOptionSet::RKOptionSet (const QDomElement &element, RKComponent *parent_compon
min_rows = xml->getIntAttribute (element, "min_rows", 0, DL_INFO);
min_rows_if_any = xml->getIntAttribute (element, "min_rows_if_any", 1, DL_INFO);
max_rows = xml->getIntAttribute (element, "max_rows", INT_MAX, DL_INFO);
- exp_mode = (ExperimentalMode) xml->getMultiChoiceAttribute (element, "exp_mode", "regular;detached;tabbed", 1, DL_INFO);
+ exp_mode = (ExperimentalMode) xml->getMultiChoiceAttribute (element, "exp_mode", "regular;detached;tabbed", 2, DL_INFO);
// build UI framework
QVBoxLayout *layout = new QVBoxLayout (this);
@@ -55,6 +56,7 @@ RKOptionSet::RKOptionSet (const QDomElement &element, RKComponent *parent_compon
if (exp_mode != Detached) layout->addWidget (switcher);
user_area = new KVBox (this);
switcher->addWidget (user_area);
+ if (exp_mode == Tabbed) tabslide = new RKTabSlide (user_area);
updating_notice = new QLabel (i18n ("Updating status, please wait"), this);
switcher->addWidget (updating_notice);
update_timer.setInterval (0);
@@ -78,10 +80,10 @@ RKOptionSet::RKOptionSet (const QDomElement &element, RKComponent *parent_compon
// first build the contents, as we will need to refer to the elements inside, later
model = 0;
display = 0; // will be created from the builder, on demand -> createDisplay ()
- contents_container = new RKComponent (this, user_area);
+ contents_container = new RKComponent (this, exp_mode == Tabbed ? tabslide->contentArea () : user_area);
QDomElement content_element = xml->getChildElement (element, "content", DL_ERROR);
RKComponentBuilder *builder = new RKComponentBuilder (contents_container, content_element);
- builder->buildElement (content_element, *xml, user_area, false); // NOTE that parent widget != parent component, here, by intention. The point is that the display should not be disabled along with the contents
+ builder->buildElement (content_element, *xml, exp_mode == Tabbed ? tabslide->contentArea () : user_area, false); // NOTE that parent widget != parent component, here, by intention. The point is that the display should not be disabled along with the contents
builder->parseLogic (xml->getChildElement (element, "logic", DL_INFO), *xml, false);
builder->makeConnections ();
addChild ("contents", contents_container);
@@ -214,6 +216,7 @@ RKComponent *RKOptionSet::createDisplay (bool show_index, QWidget *parent) {
display_show_index = show_index;
model = new RKOptionSetDisplayModel (this);
if (exp_mode == Detached) display->setItemDelegate (new RKOptionSetDelegate (this));
+ if (exp_mode == Tabbed) tabslide->tabBar ()->setModel (model);
}
display_buttons = new KHBox (dummy);
@@ -893,7 +896,7 @@ void RKOptionSetDelegate::paint (QPainter *painter, const QStyleOptionViewItem &
button.rect = option.rect;
button.text = i18n ("Edit");
button.state = QStyle::State_Enabled;
- QApplication::style()->drawControl( QStyle::CE_PushButton, &button, painter);
+ QApplication::style ()->drawControl (QStyle::CE_PushButton, &button, painter);
} else {
QItemDelegate::paint (painter, option, index);
}
diff --git a/rkward/plugin/rkoptionset.h b/rkward/plugin/rkoptionset.h
index fe6be90..cf93d44 100644
--- a/rkward/plugin/rkoptionset.h
+++ b/rkward/plugin/rkoptionset.h
@@ -25,6 +25,7 @@
#include <QTimer>
#include <QSet>
+class RKTabSlide;
class QTreeView;
class QPushButton;
class RKOptionSetDisplayModel;
@@ -119,6 +120,7 @@ friend class RKOptionSetDisplayModel;
QStackedWidget *switcher;
QWidget *updating_notice;
QWidget *user_area;
+ RKTabSlide *tabslide;
void updateUnfinishedRows ();
int return_to_row;
QTimer update_timer;
More information about the rkward-tracker
mailing list