From ecd18eb062a8878db8464789f6428a74d0896008 Mon Sep 17 00:00:00 2001 From: Diego Iastrubni Date: Thu, 25 Jan 2024 23:25:58 +0200 Subject: [PATCH] New Widget: TabHeader A new tab header that sites above (bellow?) the tab view. Basic draing, no interaction, all tabs have the same size, no close button. --- CMakeLists.txt | 2 ++ src/tabheader.cpp | 73 +++++++++++++++++++++++++++++++++++++++++++++++ src/tabheader.h | 28 ++++++++++++++++++ 3 files changed, 103 insertions(+) create mode 100644 src/tabheader.cpp create mode 100644 src/tabheader.h diff --git a/CMakeLists.txt b/CMakeLists.txt index e181569..4542e50 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -95,6 +95,8 @@ set(SVISION_SOURCES src/spinbox.h src/stackwidget.cpp src/stackwidget.h + src/tabheader.cpp + src/tabheader.h src/theme.cpp src/theme.h src/timer.cpp diff --git a/src/tabheader.cpp b/src/tabheader.cpp new file mode 100644 index 0000000..e036bcf --- /dev/null +++ b/src/tabheader.cpp @@ -0,0 +1,73 @@ +/* + * This file is part of SVision2 + * Copyright (c) Diego Iastrubni + * + * SPDX-License-Identifier: MIT + */ + +#include "tabheader.h" +#include "theme.h" + +TabHeader::TabHeader() : Widget() { + // +} + +auto TabHeader::add_tab(const std::string_view name) -> int { + this->names.push_back(name); + return this->names.size() - 1; +} + +auto TabHeader::remove_tab(int index) -> void { this->names.erase(this->names.begin() + index); } + +auto TabHeader::set_active_tab(int index) -> void { + this->active_tab = index; + this->invalidate(); +} + +auto TabHeader::get_tab_string(int index) const -> std::string_view { + if (index < 0 || index >= names.size()) { + return ""; + } + return this->names[index]; +} + +auto default_padding_y = 5; +auto default_padding_x = 20; + +auto TabHeader::draw() -> void { + auto theme = get_theme(); + auto offset = 0; + auto &font = theme->font; + + auto active_bg = theme->colors.button_background_2; + auto non_active_bg = Darker(theme->colors.button_background_1); + + theme->draw_widget_background(content, has_focus); + + this->content.fill(0); + auto i = 0; + for (auto s : names) { + auto is_active_tab = i == this->active_tab; + auto padding_x = default_padding_x; + auto padding_y = 5; + + auto tab_size = font.text_size(s); + auto bg_color = i == active_tab ? active_bg : non_active_bg; + auto position_y = is_active_tab ? 0 : padding_y; + + this->content.fill_rect(offset, position_y, tab_size.width + padding_x * 2, + tab_size.height + padding_y * 2, bg_color); + + font.write(this->content, {offset + padding_x, padding_y}, s, 0x00); + offset += tab_size.width; + offset += padding_x + padding_x; + i++; + } +} + +auto TabHeader::size_hint() const -> Size { + auto hint = this->get_theme()->font.text_size("X"); + hint.width = 0; + hint.height += default_padding_y * 2; + return hint; +} diff --git a/src/tabheader.h b/src/tabheader.h new file mode 100644 index 0000000..65c5222 --- /dev/null +++ b/src/tabheader.h @@ -0,0 +1,28 @@ +/* + * This file is part of SVision2 + * Copyright (c) Diego Iastrubni + * + * SPDX-License-Identifier: MIT + */ + +#pragma once + +#include + +struct TabHeader : Widget { + std::vector names; + + TabHeader(); + + auto add_tab(const std::string_view name) -> int; + auto remove_tab(int index) -> void; + auto get_tab_string(int index) const -> std::string_view; + auto set_active_tab(int index) -> void; + auto get_active_tab() const -> int { return active_tab; } + + virtual auto draw() -> void override; + virtual auto size_hint() const -> Size override; + + private: + int active_tab = 0; +};