ui/qt/container.cpp

Fri, 15 Nov 2024 21:16:18 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Fri, 15 Nov 2024 21:16:18 +0100
branch
newapi
changeset 383
03599608d555
parent 130
212b63dd61be
permissions
-rw-r--r--

add UiObject reference counting (GTK)

/*
 * 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;
}

mercurial