--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ui/qt/container.cpp Wed Dec 09 11:32:01 2020 +0100 @@ -0,0 +1,256 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2014 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdio.h> +#include "container.h" + +#include <QSpacerItem> +#include <QStackedWidget> + + +/* -------------------- UiBoxContainer -------------------- */ + +UiBoxContainer::UiBoxContainer(QBoxLayout* box) { + this->current = NULL; + this->menu = NULL; + this->box = box; + box->setContentsMargins(QMargins(0,0,0,0)); + box->setSpacing(0); + + ui_reset_layout(layout); +} + +void UiBoxContainer::add(QWidget* widget, bool fill) { + if(layout.fill != UI_LAYOUT_UNDEFINED) { + fill = ui_lb2bool(layout.fill); + } + + if(hasStretchedWidget && fill) { + fill = false; + fprintf(stderr, "UiError: container has 2 filled widgets"); + } + + box->addWidget(widget, fill); + + if(!hasStretchedWidget) { + QSpacerItem *newspace = new QSpacerItem(0, 0, QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + box->removeItem(space); + box->addSpacerItem(newspace); + space = newspace; + } + + if(fill) { + hasStretchedWidget = true; + } + ui_reset_layout(layout); + current = widget; +} + +UIWIDGET ui_box(UiObject *obj, QBoxLayout::Direction dir) { + UiContainer *ct = uic_get_current_container(obj); + QWidget *widget = new QWidget(); + QBoxLayout *box = new QBoxLayout(dir); + widget->setLayout(box); + ct->add(widget, true); + + UiObject *newobj = uic_object_new(obj, widget); + newobj->container = new UiBoxContainer(box); + uic_obj_add(obj, newobj); + + return widget; +} + +UIWIDGET ui_vbox(UiObject *obj) { + return ui_box(obj, QBoxLayout::TopToBottom); +} + +UIWIDGET ui_hbox(UiObject *obj) { + return ui_box(obj, QBoxLayout::LeftToRight); +} + + + +/* -------------------- UiGridContainer -------------------- */ + +UiGridContainer::UiGridContainer(QGridLayout* grid, int margin, int columnspacing, int rowspacing) { + this->current = NULL; + this->menu = NULL; + this->grid = grid; + grid->setContentsMargins(QMargins(margin, margin, margin, margin)); + grid->setHorizontalSpacing(columnspacing); + grid->setVerticalSpacing(rowspacing); + ui_reset_layout(layout); +} + +void UiGridContainer::add(QWidget* widget, bool fill) { + if(layout.newline) { + x = 0; + y++; + } + + Qt::Alignment alignment = Qt::AlignTop; + grid->setColumnStretch(x, layout.hexpand ? 1 : 0); + if(layout.vexpand) { + grid->setRowStretch(y, 1); + alignment = 0; + } else { + grid->setRowStretch(y, 0); + } + + int gwidth = layout.gridwidth > 0 ? layout.gridwidth : 1; + + grid->addWidget(widget, y, x, 1, gwidth, alignment); + x += gwidth; + + ui_reset_layout(layout); + current = widget; +} + +UIWIDGET ui_grid(UiObject *obj) { + return ui_grid_sp(obj, 0, 0, 0); +} + +UIWIDGET ui_grid_sp(UiObject *obj, int margin, int columnspacing, int rowspacing) { + UiContainer *ct = uic_get_current_container(obj); + QWidget *widget = new QWidget(); + QGridLayout *grid = new QGridLayout(); + widget->setLayout(grid); + ct->add(widget, true); + + UiObject *newobj = uic_object_new(obj, widget); + newobj->container = new UiGridContainer(grid, margin, columnspacing, rowspacing); + uic_obj_add(obj, newobj); + + return widget; +} + + +/* -------------------- UiTabViewContainer -------------------- */ + +UiTabViewContainer::UiTabViewContainer(QTabWidget* tabwidget) { + this->current = NULL; + this->menu = NULL; + this->tabwidget = tabwidget; +} + +void UiTabViewContainer::add(QWidget* widget, bool fill) { + QString str = QString::fromUtf8(layout.label); + tabwidget->addTab(widget, str); +} + + +/* -------------------- UiStackContainer -------------------- */ + +UiStackContainer::UiStackContainer(QStackedWidget *stack) { + this->stack = stack; +} + +void UiStackContainer::add(QWidget* widget, bool fill) { + stack->addWidget(widget); + current = widget; +} + +UIWIDGET ui_tabview(UiObject *obj) { + QStackedWidget *tabwidget = new QStackedWidget(); + + UiContainer *ct = uic_get_current_container(obj); + ct->add(tabwidget, true); + + UiObject *tabviewobj = uic_object_new(obj, tabwidget); + tabviewobj->container = new UiStackContainer(tabwidget); + uic_obj_add(obj, tabviewobj); + + return tabwidget; +} + +void ui_tab(UiObject *obj, char *title) { + UiContainer *ct = uic_get_current_container(obj); + ct->layout.label = title; + ui_vbox(obj); +} + +void ui_select_tab(UIWIDGET tabview, int tab) { + QStackedWidget *w = (QStackedWidget*)tabview; + w->setCurrentIndex(tab); +} + + +/* -------------------- UiSidebarContainer -------------------- */ + +UiSidebarContainer::UiSidebarContainer(QSplitter *splitter) { + this->splitter = splitter; +} + +UIWIDGET ui_sidebar(UiObject *obj) { + QSplitter *splitter = new QSplitter(Qt::Horizontal); + UiContainer *ct = uic_get_current_container(obj); + ct->add(splitter, true); + + UiObject *left = uic_object_new(obj, splitter); + left->container = new UiSidebarContainer(splitter); + + UiObject *right = uic_object_new(obj, splitter); + right->container = new UiSidebarContainer(splitter); + + uic_obj_add(obj, right); + uic_obj_add(obj, left); + + return splitter; +} + +void UiSidebarContainer::add(QWidget *widget, bool fill) { + splitter->addWidget(widget); +} + + +/* -------------------- layout functions -------------------- */ + +void ui_layout_fill(UiObject *obj, UiBool fill) { + UiContainer *ct = uic_get_current_container(obj); + ct->layout.fill = ui_bool2lb(fill); +} + +void ui_layout_hexpand(UiObject *obj, UiBool expand) { + UiContainer *ct = uic_get_current_container(obj); + ct->layout.hexpand = expand; +} + +void ui_layout_vexpand(UiObject *obj, UiBool expand) { + UiContainer *ct = uic_get_current_container(obj); + ct->layout.vexpand = expand; +} + +void ui_layout_gridwidth(UiObject *obj, int width) { + UiContainer *ct = uic_get_current_container(obj); + ct->layout.gridwidth = width; +} + +void ui_newline(UiObject *obj) { + UiContainer *ct = uic_get_current_container(obj); + ct->layout.newline = TRUE; +}