mirror of
https://github.com/aseprite/aseprite.git
synced 2025-02-11 09:40:42 +00:00
[lua] Add selected tab retrieval/selection through Dialog's data and possibility to set the tabs selector at the bottom
This commit is contained in:
parent
0ae408fe4e
commit
d21f47f827
@ -207,6 +207,7 @@ if(ENABLE_SCRIPTING)
|
|||||||
script/slices_class.cpp
|
script/slices_class.cpp
|
||||||
script/sprite_class.cpp
|
script/sprite_class.cpp
|
||||||
script/sprites_class.cpp
|
script/sprites_class.cpp
|
||||||
|
script/tabs_widget.cpp
|
||||||
script/tag_class.cpp
|
script/tag_class.cpp
|
||||||
script/tags_class.cpp
|
script/tags_class.cpp
|
||||||
script/tile_class.cpp
|
script/tile_class.cpp
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "app/script/graphics_context.h"
|
#include "app/script/graphics_context.h"
|
||||||
#include "app/script/keys.h"
|
#include "app/script/keys.h"
|
||||||
#include "app/script/luacpp.h"
|
#include "app/script/luacpp.h"
|
||||||
|
#include "app/script/tabs_widget.h"
|
||||||
#include "app/ui/button_set.h"
|
#include "app/ui/button_set.h"
|
||||||
#include "app/ui/color_button.h"
|
#include "app/ui/color_button.h"
|
||||||
#include "app/ui/color_shades.h"
|
#include "app/ui/color_shades.h"
|
||||||
@ -76,11 +77,10 @@ struct Dialog {
|
|||||||
std::map<std::string, ui::Widget*> labelWidgets;
|
std::map<std::string, ui::Widget*> labelWidgets;
|
||||||
int currentRadioGroup = 0;
|
int currentRadioGroup = 0;
|
||||||
|
|
||||||
// Members used to hold current state about the creation of a group
|
// Member used to hold current state about the creation of a tabs
|
||||||
// of tabs. After creation, these members are reset to their initial
|
// widget. After creation it is reset to null to be ready for the
|
||||||
// empty state to be ready for the next group of tabs.
|
// creation of the next tabs widget.
|
||||||
std::vector<ui::Grid*> tabs;
|
app::script::Tabs* wipTab = nullptr;
|
||||||
HBox* tabsSelector = nullptr;
|
|
||||||
|
|
||||||
// Used to create a new row when a different kind of widget is added
|
// Used to create a new row when a different kind of widget is added
|
||||||
// in the dialog.
|
// in the dialog.
|
||||||
@ -581,15 +581,23 @@ int Dialog_add_widget(lua_State* L, Widget* widget)
|
|||||||
if (!id.empty())
|
if (!id.empty())
|
||||||
dlg->labelWidgets[id] = labelWidget;
|
dlg->labelWidgets[id] = labelWidget;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
dlg->currentGrid->addChildInCell(new ui::HBox, 1, 1, ui::LEFT | ui::TOP);
|
// For tabs we don't want the empty space of an unspecified label.
|
||||||
|
if (widget->type() != Tabs::Type()) {
|
||||||
|
dlg->currentGrid->addChildInCell(new ui::HBox, 1, 1, ui::LEFT | ui::TOP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
auto hbox = new ui::HBox;
|
auto hbox = new ui::HBox;
|
||||||
if (widget->type() == ui::kButtonWidget)
|
if (widget->type() == ui::kButtonWidget)
|
||||||
hbox->enableFlags(ui::HOMOGENEOUS);
|
hbox->enableFlags(ui::HOMOGENEOUS);
|
||||||
|
|
||||||
|
// For tabs we don't want the empty space of an unspecified label, so
|
||||||
|
// span 2 columns.
|
||||||
|
const int hspan = (widget->type() == Tabs::Type() ? 2: 1);
|
||||||
dlg->currentGrid->addChildInCell(
|
dlg->currentGrid->addChildInCell(
|
||||||
hbox, 1, 1,
|
hbox, hspan, 1,
|
||||||
ui::HORIZONTAL | (vexpand ? ui::VERTICAL: ui::TOP));
|
ui::HORIZONTAL | (vexpand ? ui::VERTICAL: ui::TOP));
|
||||||
|
|
||||||
dlg->hbox = hbox;
|
dlg->hbox = hbox;
|
||||||
@ -1295,27 +1303,35 @@ int Dialog_tab(lua_State* L)
|
|||||||
auto dlg = get_obj<Dialog>(L, 1);
|
auto dlg = get_obj<Dialog>(L, 1);
|
||||||
|
|
||||||
std::string text;
|
std::string text;
|
||||||
|
std::string id;
|
||||||
if (lua_istable(L, 2)) {
|
if (lua_istable(L, 2)) {
|
||||||
int type = lua_getfield(L, 2, "text");
|
int type = lua_getfield(L, 2, "id");
|
||||||
|
if (type != LUA_TNIL)
|
||||||
|
id = lua_tostring(L, -1);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
type = lua_getfield(L, 2, "text");
|
||||||
if (type != LUA_TNIL) {
|
if (type != LUA_TNIL) {
|
||||||
text = lua_tostring(L, -1);
|
text = lua_tostring(L, -1);
|
||||||
}
|
}
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
// If there was no id set, then use the tab text as the tab id.
|
||||||
|
if (id.empty()) id = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dlg->wipTab) {
|
||||||
|
dlg->wipTab = new app::script::Tabs(ui::CENTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto tabContent = new ui::Grid(2, false);
|
auto tabContent = new ui::Grid(2, false);
|
||||||
|
tabContent->setExpansive(true);
|
||||||
tabContent->setVisible(false);
|
tabContent->setVisible(false);
|
||||||
tabContent->setText(text);
|
tabContent->setText(text);
|
||||||
dlg->tabs.push_back(tabContent);
|
tabContent->setId(id.c_str());
|
||||||
|
dlg->wipTab->addTab(tabContent);
|
||||||
dlg->currentGrid = tabContent;
|
dlg->currentGrid = tabContent;
|
||||||
|
|
||||||
// If this is the first tab create the tabs selector container.
|
|
||||||
if (dlg->tabs.size() == 1) {
|
|
||||||
dlg->tabsSelector = new HBox();
|
|
||||||
dlg->grid.addChildInCell(dlg->tabsSelector, 2, 1, ui::HORIZONTAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
dlg->grid.addChildInCell(tabContent, 2, 1, ui::HORIZONTAL | ui::VERTICAL);
|
|
||||||
lua_pushvalue(L, 1);
|
lua_pushvalue(L, 1);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -1325,7 +1341,7 @@ int Dialog_endtabs(lua_State* L)
|
|||||||
auto dlg = get_obj<Dialog>(L, 1);
|
auto dlg = get_obj<Dialog>(L, 1);
|
||||||
|
|
||||||
// There is no starting :tab(), do nothing then.
|
// There is no starting :tab(), do nothing then.
|
||||||
if (dlg->tabs.empty()) {
|
if (!dlg->wipTab) {
|
||||||
lua_pushvalue(L, 1);
|
lua_pushvalue(L, 1);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -1336,70 +1352,35 @@ int Dialog_endtabs(lua_State* L)
|
|||||||
int type = lua_getfield(L, 2, "selected");
|
int type = lua_getfield(L, 2, "selected");
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case LUA_TSTRING: {
|
case LUA_TSTRING: {
|
||||||
// Find the tab index with the specified text.
|
// Find the tab index by id first, if not found try by text then.
|
||||||
std::string selTabText = lua_tostring(L, -1);
|
std::string selTabStr = lua_tostring(L, -1);
|
||||||
for (int i=0; i<dlg->tabs.size(); ++i) {
|
selectedTab = dlg->wipTab->tabIndexById(selTabStr);
|
||||||
if (dlg->tabs[i]->text() == selTabText) {
|
if (selectedTab < 0)
|
||||||
selectedTab = i;
|
selectedTab = dlg->wipTab->tabIndexByText(selTabStr);
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LUA_TNUMBER:
|
case LUA_TNUMBER:
|
||||||
selectedTab = std::clamp<int>(lua_tointeger(L, -1), 1, dlg->tabs.size()) - 1;
|
selectedTab = std::clamp<int>(lua_tointeger(L, -1), 1, dlg->wipTab->size()) - 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
|
|
||||||
type = lua_getfield(L, 2, "align");
|
type = lua_getfield(L, 2, "align");
|
||||||
if(type != LUA_TNIL) {
|
if (type != LUA_TNIL) {
|
||||||
int v = lua_tointeger(L, -1) & (ui::CENTER | ui::LEFT | ui::RIGHT);
|
// Filter invalid flags.
|
||||||
// Set align only if it has a valid value.
|
int v = lua_tointeger(L, -1) & (ui::CENTER | ui::LEFT | ui::RIGHT | ui::TOP | ui::BOTTOM);
|
||||||
if (v) align = v;
|
if (v) align = v;
|
||||||
}
|
}
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
}
|
}
|
||||||
|
dlg->wipTab->setSelectorFlags(align);
|
||||||
|
dlg->wipTab->selectTab(selectedTab);
|
||||||
|
|
||||||
// Create the tabs selector's buttonset
|
auto newTab = dlg->wipTab;
|
||||||
auto widget = new app::ButtonSet(dlg->tabs.size());
|
|
||||||
for (int i=0; i<dlg->tabs.size(); ++i) {
|
|
||||||
auto item = widget->addItem(dlg->tabs[i]->text());
|
|
||||||
item->setSelected(i == selectedTab);
|
|
||||||
dlg->tabs[i]->setVisible(i == selectedTab);
|
|
||||||
}
|
|
||||||
auto tabs = dlg->tabs;
|
|
||||||
widget->ItemChange.connect([dlg, tabs](ButtonSet::Item* selItem) {
|
|
||||||
for (auto tab : tabs) {
|
|
||||||
tab->setVisible(selItem->text() == tab->text());
|
|
||||||
}
|
|
||||||
dlg->window.remapWindow();
|
|
||||||
});
|
|
||||||
widget->initTheme();
|
|
||||||
ui::Separator* sep;
|
|
||||||
if (align & ui::CENTER || align & ui::RIGHT) {
|
|
||||||
sep = new ui::Separator("", ui::HORIZONTAL);
|
|
||||||
sep->setExpansive(true);
|
|
||||||
dlg->tabsSelector->addChild(sep);
|
|
||||||
}
|
|
||||||
dlg->tabsSelector->addChild(widget);
|
|
||||||
if (align & ui::CENTER || align & ui::LEFT) {
|
|
||||||
sep = new ui::Separator("", ui::HORIZONTAL);
|
|
||||||
sep->setExpansive(true);
|
|
||||||
dlg->tabsSelector->addChild(sep);
|
|
||||||
}
|
|
||||||
// Add tab's bottom separator
|
|
||||||
sep = new ui::Separator("", ui::HORIZONTAL);
|
|
||||||
sep->setExpansive(true);
|
|
||||||
dlg->grid.addChildInCell(sep, 2, 1, ui::HORIZONTAL);
|
|
||||||
|
|
||||||
// Clear state to be ready for the next tabs creation
|
|
||||||
dlg->tabsSelector = nullptr;
|
|
||||||
dlg->tabs.clear();
|
|
||||||
dlg->currentGrid = &dlg->grid;
|
dlg->currentGrid = &dlg->grid;
|
||||||
|
dlg->wipTab = nullptr;
|
||||||
|
|
||||||
lua_pushvalue(L, 1);
|
return Dialog_add_widget(L, newTab);
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int Dialog_modify(lua_State* L)
|
int Dialog_modify(lua_State* L)
|
||||||
@ -1704,6 +1685,10 @@ int Dialog_get_data(lua_State* L)
|
|||||||
else if (auto filenameField = dynamic_cast<const FilenameField*>(widget)) {
|
else if (auto filenameField = dynamic_cast<const FilenameField*>(widget)) {
|
||||||
lua_pushstring(L, filenameField->filename().c_str());
|
lua_pushstring(L, filenameField->filename().c_str());
|
||||||
}
|
}
|
||||||
|
else if (auto tabs = dynamic_cast<const app::script::Tabs*>(widget)) {
|
||||||
|
std::string tabStr = tabs->tabId(tabs->selectedTab());
|
||||||
|
lua_pushstring(L, tabStr.c_str());
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
lua_pushnil(L);
|
lua_pushnil(L);
|
||||||
}
|
}
|
||||||
@ -1794,6 +1779,16 @@ int Dialog_set_data(lua_State* L)
|
|||||||
if (auto p = lua_tostring(L, -1))
|
if (auto p = lua_tostring(L, -1))
|
||||||
filenameField->setFilename(p);
|
filenameField->setFilename(p);
|
||||||
}
|
}
|
||||||
|
else if (auto tabs = dynamic_cast<app::script::Tabs*>(widget)) {
|
||||||
|
int type = lua_type(L, -1);
|
||||||
|
if (type == LUA_TNUMBER)
|
||||||
|
tabs->selectTab(lua_tointeger(L, -1)-1);
|
||||||
|
else if (type == LUA_TSTRING) {
|
||||||
|
std::string tabStr = lua_tostring(L, -1);
|
||||||
|
int tabIndex = tabs->tabIndexById(tabStr);
|
||||||
|
tabs->selectTab(tabIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -474,6 +474,9 @@ Engine::Engine()
|
|||||||
setfield_integer(L, "LEFT", ui::LEFT);
|
setfield_integer(L, "LEFT", ui::LEFT);
|
||||||
setfield_integer(L, "CENTER", ui::CENTER);
|
setfield_integer(L, "CENTER", ui::CENTER);
|
||||||
setfield_integer(L, "RIGHT", ui::RIGHT);
|
setfield_integer(L, "RIGHT", ui::RIGHT);
|
||||||
|
setfield_integer(L, "TOP", ui::TOP);
|
||||||
|
setfield_integer(L, "BOTTOM", ui::BOTTOM);
|
||||||
|
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
|
|
||||||
// Register classes/prototypes
|
// Register classes/prototypes
|
||||||
|
184
src/app/script/tabs_widget.cpp
Normal file
184
src/app/script/tabs_widget.cpp
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
// Aseprite
|
||||||
|
// Copyright (c) 2022-2023 Igara Studio S.A.
|
||||||
|
//
|
||||||
|
// This program is distributed under the terms of
|
||||||
|
// the End-User License Agreement for Aseprite.
|
||||||
|
|
||||||
|
#include "app/script/tabs_widget.h"
|
||||||
|
|
||||||
|
#ifdef ENABLE_UI
|
||||||
|
|
||||||
|
using namespace ui;
|
||||||
|
|
||||||
|
namespace app {
|
||||||
|
namespace script {
|
||||||
|
|
||||||
|
// static
|
||||||
|
ui::WidgetType Tabs::Type()
|
||||||
|
{
|
||||||
|
static ui::WidgetType type = ui::kGenericWidget;
|
||||||
|
if (type == ui::kGenericWidget)
|
||||||
|
type = ui::register_widget_type();
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
Tabs::Tabs(int selectorFlags) : m_selectorFlags(selectorFlags)
|
||||||
|
{
|
||||||
|
m_sepL.setExpansive(true);
|
||||||
|
m_sepR.setExpansive(true);
|
||||||
|
m_pages.setExpansive(true);
|
||||||
|
setType(Type());
|
||||||
|
layoutChilds();
|
||||||
|
}
|
||||||
|
|
||||||
|
Tab* Tabs::addTab(Grid* content)
|
||||||
|
{
|
||||||
|
m_pages.addChild(content);
|
||||||
|
|
||||||
|
if (m_buttons.children().empty()) {
|
||||||
|
m_buttonsBox.addChild(&m_buttons);
|
||||||
|
m_buttons.ItemChange.connect([this](ButtonSet::Item* selItem) {
|
||||||
|
int oldSelectedTabIndex = m_selectedTab;
|
||||||
|
for (int i=0; i<m_pages.children().size(); ++i) {
|
||||||
|
auto tab = m_pages.children()[i];
|
||||||
|
bool isSelectedTab = selItem->text() == tab->text();
|
||||||
|
tab->setVisible(isSelectedTab);
|
||||||
|
if (isSelectedTab)
|
||||||
|
m_selectedTab = i;
|
||||||
|
}
|
||||||
|
layout();
|
||||||
|
if (oldSelectedTabIndex != m_selectedTab) {
|
||||||
|
TabChanged();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_buttons.setColumns(m_pages.children().size());
|
||||||
|
}
|
||||||
|
auto tab = new Tab();
|
||||||
|
tab->setText(content->text());
|
||||||
|
m_buttons.addItem(tab);
|
||||||
|
// Select the first tab by default.
|
||||||
|
if (m_buttons.children().size() == 1) {
|
||||||
|
selectTab(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_buttons.initTheme();
|
||||||
|
|
||||||
|
return tab;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tabs::selectTab(int index)
|
||||||
|
{
|
||||||
|
if (index >= 0 && index < m_pages.children().size()) {
|
||||||
|
for (int i=0; i<m_pages.children().size(); ++i) {
|
||||||
|
m_buttons.getItem(i)->setSelected(i == index);
|
||||||
|
m_pages.children()[i]->setVisible(i == index);
|
||||||
|
}
|
||||||
|
m_selectedTab = index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tabs::setSelectorFlags(int selectorFlags)
|
||||||
|
{
|
||||||
|
if (selectorFlags != m_selectorFlags) {
|
||||||
|
m_selectorFlags = selectorFlags;
|
||||||
|
layoutChilds();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int Tabs::tabIndexById(const std::string& id) const
|
||||||
|
{
|
||||||
|
for (int i=0; i<m_pages.children().size(); ++i) {
|
||||||
|
if (m_pages.children()[i]->id() == id)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Tabs::tabIndexByText(const std::string& text) const
|
||||||
|
{
|
||||||
|
for (int i=0; i<m_pages.children().size(); ++i) {
|
||||||
|
if (m_pages.children()[i]->text() == text)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Tabs::tabId(int index) const
|
||||||
|
{
|
||||||
|
return index >= 0 && index < m_pages.children().size() ?
|
||||||
|
m_pages.children()[index]->id() :
|
||||||
|
std::string();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Tabs::tabText(int index) const
|
||||||
|
{
|
||||||
|
return index >= 0 && index < m_pages.children().size() ?
|
||||||
|
m_pages.children()[index]->text() :
|
||||||
|
std::string();
|
||||||
|
}
|
||||||
|
|
||||||
|
int Tabs::selectedTab() const
|
||||||
|
{
|
||||||
|
return m_selectedTab;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tabs::layoutChilds()
|
||||||
|
{
|
||||||
|
// Put the tab selector at the bottom or at the top.
|
||||||
|
removeAllChildren();
|
||||||
|
if (m_selectorFlags & ui::BOTTOM) {
|
||||||
|
addChild(&m_sepTB);
|
||||||
|
addChild(&m_pages);
|
||||||
|
addChild(&m_selector);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
addChild(&m_selector);
|
||||||
|
addChild(&m_pages);
|
||||||
|
addChild(&m_sepTB);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Align the selector buttons.
|
||||||
|
m_selector.removeAllChildren();
|
||||||
|
if (m_selectorFlags & ui::LEFT) {
|
||||||
|
m_selector.addChild(&m_buttonsBox);
|
||||||
|
m_selector.addChild(&m_sepR);
|
||||||
|
}
|
||||||
|
else if (m_selectorFlags & ui::RIGHT) {
|
||||||
|
m_selector.addChild(&m_sepL);
|
||||||
|
m_selector.addChild(&m_buttonsBox);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_selector.addChild(&m_sepL);
|
||||||
|
m_selector.addChild(&m_buttonsBox);
|
||||||
|
m_selector.addChild(&m_sepR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pages::onSizeHint(ui::SizeHintEvent& ev)
|
||||||
|
{
|
||||||
|
gfx::Size prefSize(0, 0);
|
||||||
|
for (auto child : children()) {
|
||||||
|
|
||||||
|
gfx::Size childSize = child->sizeHint();
|
||||||
|
prefSize.w = std::max(childSize.w, prefSize.w);
|
||||||
|
prefSize.h = std::max(childSize.h, prefSize.h);
|
||||||
|
}
|
||||||
|
prefSize.w += border().width();
|
||||||
|
prefSize.h += border().height();
|
||||||
|
|
||||||
|
ev.setSizeHint(prefSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Tab::onClick()
|
||||||
|
{
|
||||||
|
Click();
|
||||||
|
ButtonSet::Item::onClick();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace script
|
||||||
|
} // namespace app
|
||||||
|
|
||||||
|
#endif // ENABLE_UI
|
70
src/app/script/tabs_widget.h
Normal file
70
src/app/script/tabs_widget.h
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
// Aseprite
|
||||||
|
// Copyright (C) 2023 Igara Studio S.A.
|
||||||
|
//
|
||||||
|
// This program is distributed under the terms of
|
||||||
|
// the End-User License Agreement for Aseprite.
|
||||||
|
|
||||||
|
#ifndef APP_SCRIPT_TABS_H_INCLUDED
|
||||||
|
#define APP_SCRIPT_TABS_H_INCLUDED
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "app/ui/button_set.h"
|
||||||
|
#include "ui/box.h"
|
||||||
|
#include "ui/grid.h"
|
||||||
|
#include "ui/separator.h"
|
||||||
|
#include "ui/size_hint_event.h"
|
||||||
|
#include "ui/widget.h"
|
||||||
|
|
||||||
|
namespace app {
|
||||||
|
namespace script {
|
||||||
|
|
||||||
|
class Tab : public app::ButtonSet::Item {
|
||||||
|
public:
|
||||||
|
obs::signal<void()> Click;
|
||||||
|
protected:
|
||||||
|
virtual void onClick();
|
||||||
|
};
|
||||||
|
|
||||||
|
class Pages : public ui::VBox {
|
||||||
|
protected:
|
||||||
|
void onSizeHint(ui::SizeHintEvent& ev);
|
||||||
|
};
|
||||||
|
|
||||||
|
class Tabs : public ui::VBox {
|
||||||
|
|
||||||
|
public:
|
||||||
|
static ui::WidgetType Type();
|
||||||
|
|
||||||
|
Tabs(int selectorFlags);
|
||||||
|
|
||||||
|
Tab* addTab(ui::Grid* content);
|
||||||
|
void selectTab(int index);
|
||||||
|
void setSelectorFlags(int selectorFlags);
|
||||||
|
|
||||||
|
int tabIndexById(const std::string& text) const;
|
||||||
|
int tabIndexByText(const std::string& text) const;
|
||||||
|
std::string tabId(int index) const;
|
||||||
|
std::string tabText(int index) const;
|
||||||
|
int selectedTab() const;
|
||||||
|
int size() const { return m_pages.children().size(); };
|
||||||
|
|
||||||
|
obs::signal<void()> TabChanged;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void layoutChilds();
|
||||||
|
|
||||||
|
ui::HBox m_selector;
|
||||||
|
ui::Separator m_sepL = ui::Separator(std::string(), ui::HORIZONTAL);
|
||||||
|
ui::Separator m_sepR = ui::Separator(std::string(), ui::HORIZONTAL);
|
||||||
|
ui::Separator m_sepTB = ui::Separator(std::string(), ui::HORIZONTAL);
|
||||||
|
ui::HBox m_buttonsBox;
|
||||||
|
app::ButtonSet m_buttons = app::ButtonSet(1);
|
||||||
|
Pages m_pages;
|
||||||
|
int m_selectedTab = 0;
|
||||||
|
int m_selectorFlags;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace script
|
||||||
|
} // namespace app
|
||||||
|
|
||||||
|
#endif
|
@ -129,6 +129,21 @@ void Grid::setStyle(Style* style)
|
|||||||
setGap(style->gap());
|
setGap(style->gap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Grid::setColumns(int columns)
|
||||||
|
{
|
||||||
|
if (columns == m_colstrip.size())
|
||||||
|
return;
|
||||||
|
|
||||||
|
int oldSize = m_colstrip.size();
|
||||||
|
m_colstrip.resize(columns);
|
||||||
|
for (int row=0; row<m_rowstrip.size(); ++row) {
|
||||||
|
m_cells[row].resize(m_colstrip.size());
|
||||||
|
for (int col=oldSize; col<(int)m_cells[row].size(); ++col) {
|
||||||
|
m_cells[row][col] = new Cell;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Grid::setGap(const gfx::Size& gap)
|
void Grid::setGap(const gfx::Size& gap)
|
||||||
{
|
{
|
||||||
m_colgap = gap.w;
|
m_colgap = gap.w;
|
||||||
|
@ -34,6 +34,7 @@ namespace ui {
|
|||||||
Info getChildInfo(Widget* child);
|
Info getChildInfo(Widget* child);
|
||||||
void setGap(const gfx::Size& gap);
|
void setGap(const gfx::Size& gap);
|
||||||
void setStyle(Style* style) override;
|
void setStyle(Style* style) override;
|
||||||
|
void setColumns(int columns);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Events
|
// Events
|
||||||
|
Loading…
x
Reference in New Issue
Block a user