1//============================================================================
2//
3// SSSS tt lll lll
4// SS SS tt ll ll
5// SS tttttt eeee ll ll aaaa
6// SSSS tt ee ee ll ll aa
7// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
8// SS SS tt ee ll ll aa aa
9// SSSS ttt eeeee llll llll aaaaa
10//
11// Copyright (c) 1995-2019 by Bradford W. Mott, Stephen Anthony
12// and the Stella Team
13//
14// See the file "License.txt" for information on usage and redistribution of
15// this file, and for a DISCLAIMER OF ALL WARRANTIES.
16//============================================================================
17
18#ifndef TAB_WIDGET_HXX
19#define TAB_WIDGET_HXX
20
21#include "bspf.hxx"
22
23#include "Command.hxx"
24#include "Widget.hxx"
25
26class TabWidget : public Widget, public CommandSender
27{
28 public:
29 static const int NO_WIDTH = 0;
30 static const int AUTO_WIDTH = -1;
31
32 enum {
33 kTabChangedCmd = 'TBCH'
34 };
35
36 public:
37 TabWidget(GuiObject* boss, const GUI::Font& font, int x, int y, int w, int h);
38 virtual ~TabWidget();
39
40// use Dialog::releaseFocus() when changing to another tab
41
42// Problem: how to add items to a tab?
43// First off, widget should allow non-dialog bosses, (i.e. also other widgets)
44// Could add a common base class for Widgets and Dialogs.
45// Then you add tabs using the following method, which returns a unique ID
46 int addTab(const string& title, int tabWidth = NO_WIDTH);
47// Maybe we need to remove tabs again? Hm
48 //void removeTab(int tabID);
49// Setting the active tab:
50 void setActiveTab(int tabID, bool show = false);
51// void disableTab(int tabID);
52 void activateTabs();
53 void cycleTab(int direction);
54// setActiveTab changes the value of _firstWidget. This means Widgets added afterwards
55// will be added to the active tab.
56 void setParentWidget(int tabID, Widget* parent);
57
58 int getTabWidth() { return _tabWidth; }
59 int getTabHeight() { return _tabHeight; }
60 int getActiveTab() { return _activeTab; }
61
62 void loadConfig() override;
63
64 protected:
65 void handleMouseDown(int x, int y, MouseButton b, int clickCount) override;
66 void handleMouseEntered() override;
67 void handleMouseLeft() override;
68
69 void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
70 bool handleEvent(Event::Type event) override;
71
72 void drawWidget(bool hilite) override;
73 Widget* findWidget(int x, int y) override;
74 int getChildY() const override;
75
76 private:
77 struct Tab {
78 string title;
79 Widget* firstWidget;
80 Widget* parentWidget;
81 bool enabled;
82 int tabWidth;
83
84 Tab(const string& t, int tw = NO_WIDTH,
85 Widget* first = nullptr, Widget* parent = nullptr, bool e = true)
86 : title(t), firstWidget(first), parentWidget(parent), enabled(e), tabWidth(tw) { }
87 };
88 using TabList = vector<Tab>;
89
90 TabList _tabs;
91 int _tabWidth;
92 int _tabHeight;
93 int _activeTab;
94 bool _firstTime;
95
96 enum {
97 kTabLeftOffset = 0,
98 kTabSpacing = 1,
99 kTabPadding = 4
100 };
101
102 private:
103 void updateActiveTab();
104
105 private:
106 // Following constructors and assignment operators not supported
107 TabWidget() = delete;
108 TabWidget(const TabWidget&) = delete;
109 TabWidget(TabWidget&&) = delete;
110 TabWidget& operator=(const TabWidget&) = delete;
111 TabWidget& operator=(TabWidget&&) = delete;
112};
113
114#endif
115