5#include "fifechan/widgets/tabbedarea.hpp"
10#include "fifechan/exception.hpp"
11#include "fifechan/focushandler.hpp"
12#include "fifechan/font.hpp"
13#include "fifechan/graphics.hpp"
14#include "fifechan/widgets/tab.hpp"
18 TabbedArea::TabbedArea() : mTabContainer(new
Container()), mWidgetContainer(new
Container())
22 addMouseListener(
this);
24 mTabContainer->setOpaque(
false);
25 mTabContainer->setLayout(Container::LayoutPolicy::Horizontal);
27 mWidgetContainer->setLayout(Container::LayoutPolicy::Vertical);
28 mWidgetContainer->setPadding(6);
31 add(mWidgetContainer);
34 TabbedArea::~TabbedArea()
36 remove(mTabContainer);
37 remove(mWidgetContainer);
40 delete mWidgetContainer;
48 if (tab->
getLayout() == Container::LayoutPolicy::Absolute) {
52 mTabs.emplace_back(tab, widget);
63 if (index >=
mTabs.size()) {
64 throwException(
"No such tab index.");
72 int tabIndexToBeSelected = -1;
76 int const mTabsSize =
static_cast<int>(
mTabs.size());
77 if (index ==
static_cast<int>((mTabsSize - 1) != 0 && mTabsSize >= 2)) {
78 tabIndexToBeSelected = index - 1;
79 }
else if (index == mTabsSize - 1 && mTabsSize == 1) {
80 tabIndexToBeSelected = -1;
82 tabIndexToBeSelected = index;
86 auto iter = std::ranges::find_if(
mTabs, [tab](std::pair<Tab*, Widget*>
const & p) {
87 return p.first == tab;
89 if (iter !=
mTabs.end()) {
94 auto iter2 = std::ranges::find_if(
mTabsToDelete, [tab](std::unique_ptr<Tab>
const & t) {
95 return t.get() == tab;
101 if (tabIndexToBeSelected == -1) {
118 if (index >=
mTabs.size()) {
119 throwException(
"No such tab index.");
132 if (index >=
mTabs.size()) {
133 throwException(
"No such tab index.");
145 for (i = 0; i <
mTabs.size(); i++) {
151 for (i = 0; i <
mTabs.size(); i++) {
152 if (
mTabs[i].first == tab) {
163 for (i = 0; i <
mTabs.size(); i++) {
202 Color highlightColor = faceColor + 0x303030;
203 highlightColor.
a = alpha;
204 Color shadowColor = faceColor - 0x303030;
205 shadowColor.
a = alpha;
273 int maxTabHeight = 0;
277 for (
auto& mTab :
mTabs) {
280 maxTabWidth = std::max(mTab.first->getWidth(), maxTabWidth);
281 maxTabHeight = std::max(mTab.first->getHeight(), maxTabHeight);
284 if (
getLayout() == Container::LayoutPolicy::Vertical) {
288 }
else if (
getLayout() == Container::LayoutPolicy::Horizontal) {
298 int maxTabHeight = 0;
300 for (i = 0; i <
mTabs.size(); i++) {
301 maxTabWidth = std::max(
mTabs[i].first->getWidth(), maxTabWidth);
302 maxTabHeight = std::max(
mTabs[i].first->getHeight(), maxTabHeight);
305 if (
getLayout() == Container::LayoutPolicy::Vertical) {
307 for (i = 0; i <
mTabs.size(); i++) {
308 Tab* tab =
mTabs[i].first;
312 }
else if (
getLayout() == Container::LayoutPolicy::Horizontal) {
314 for (i = 0; i <
mTabs.size(); i++) {
315 Tab* tab =
mTabs[i].first;
392 if (std::cmp_greater_equal(index,
mTabs.size())) {
410 if (mouseEvent.
getButton() == MouseEvent::Button::Left) {
412 Tab* tab =
dynamic_cast<Tab*
>(widget);
414 if (tab !=
nullptr) {
429 Tab* tab =
dynamic_cast<Tab*
>(
event.getSource());
431 if (tab !=
nullptr) {
441 Tab* tab =
dynamic_cast<Tab*
>(source);
443 if (tab ==
nullptr) {
444 throwException(
"Received an action from a widget that's not a tab!");
455 for (
auto const & tabEntry :
mTabs) {
456 tabEntry.first->setBaseColor(color);
Represents an action trigger (e.g., button click).
uint8_t a
Alpha color component (0-255).
A composite widget capable of holding and managing child widgets.
virtual void setLayout(LayoutPolicy policy)
Sets the layout of the container.
LayoutPolicy
The layout policy of the container.
virtual LayoutPolicy getLayout() const
Gets the layout of the container.
Base class for all GUI event objects.
Widget * getSource() const
Gets the source widget of the event.
Abstract interface providing primitive drawing functions (lines, rectangles, etc.).
virtual void drawLine(int x1, int y1, int x2, int y2)=0
Draws a line.
virtual void setColor(Color const &color)=0
Sets the color to use when drawing.
virtual void fillRectangle(Rectangle const &rectangle)=0
Draws a filled rectangle.
Key const & getKey() const
Gets the key of the event.
int getValue() const
Gets the value of the key.
Represents a mouse event.
int getX() const
Gets the x coordinate of the mouse event.
int getY() const
Gets the y coordinate of the mouse event.
MouseEvent::Button getButton() const
Gets the button of the mouse event.
Represents a rectangular area (X, Y, Width, Height).
int width
Holds the width of the rectangle.
int y
Holds the x coordinate of the rectangle.
int x
Holds the x coordinate of the rectangle.
int height
Holds the height of the rectangle.
void setTabbedArea(TabbedArea *tabbedArea)
Sets the tabbed area the tab should be a part of.
Container * mTabContainer
Holds the container for the tabs.
bool mOpaque
True if the tabbed area is opaque, false otherwise.
virtual bool isUniformSize() const
True if the tab container tries to expand the childs to a uniform size.
void resizeToContent(bool recursion) override
Resize this widget to fit its content.
virtual unsigned int getHorizontalSpacing() const
Get the horizontal spacing between rows.
virtual unsigned int getVerticalSpacing() const
Get the vertical spacing between rows.
virtual int getSelectedTabIndex() const
Gets the index of the selected tab.
Rectangle getChildrenArea() override
Gets the area of the widget occupied by the widget's children.
void setHeight(int height)
Set the height of the tabbed area in pixels.
void mousePressed(MouseEvent &mouseEvent) override
Called when a mouse button has been pressed on the widget area.
virtual void setUniformSize(bool uniform)
If enabled, the free space is distributed in a way that the size of the childrens will be equal (if p...
void setDimension(Rectangle const &dimension)
Set the area dimension for the tabbed area.
virtual void death(Event const &event)
DeathListener callback invoked when a child widget dies.
virtual bool isTabSelected(unsigned int index) const
Checks if a tab given an index is selected or not.
virtual void setHorizontalSpacing(unsigned int spacing)
Set the horizontal spacing between columns.
virtual void setSelectedTab(unsigned int index)
Sets a tab given an index to be selected.
void setLayout(Container::LayoutPolicy policy)
Sets the layout of the tabbedarea.
void setBaseColor(Color const &color) override
Set the base/background color used for the tabbed area.
virtual void addTab(Tab *tab, Widget *widget)
Adds a tab to the tabbed area.
void action(ActionEvent const &actionEvent) override
Called when an action is received from a widget.
void adjustTabPositions()
Adjusts the positions of the tabs.
void setSize(int width, int height)
Set the size (width and height) of the tabbed area in pixels.
void keyPressed(KeyEvent &keyEvent) override
Called if a key is pressed when the widget has keyboard focus.
void setWidth(int width)
Set the width of the tabbed area in pixels.
Container * mWidgetContainer
Holds the container for the widgets.
Widget * getBackgroundWidget()
Get the background widget, or nullptr if none is set.
void adjustSize() override
Adjusts the size of the tab container and the widget container.
std::vector< std::unique_ptr< Tab > > mTabsToDelete
Holds a vector of tabs to delete in the destructor.
Container::LayoutPolicy getLayout() const
Gets the layout of the tabbedarea.
std::vector< std::pair< Tab *, Widget * > > mTabs
A map between a tab and a widget to display when the tab is selected.
void setBackgroundWidget(Widget *widget)
Set the background widget which is drawn behind tabs.
int getNumberOfTabs() const
Returns the number of tabs in this tabbed area.
virtual void removeTabWithIndex(unsigned int index)
Removes a tab from the tabbed area.
virtual void setVerticalSpacing(unsigned int spacing)
Set the vertical spacing between rows.
void setOpaque(bool opaque)
Sets the tabbed area to be opaque or not.
Tab * getSelectedTab() const
Gets the selected tab.
virtual void removeTab(Tab *tab)
Removes a tab from the tabbed area.
bool isOpaque() const
Checks if the tabbed area is opaque or not.
Tab * mSelectedTab
Holds the selected tab.
void draw(Graphics *graphics) override
Draws the widget.
void expandContent(bool recursion) override
Expands child widgets to fit this widget's size.