1 // Copyright (C) 2007 Mark Pustjens <pustjens@dds.nl>
2 // Copyright (C) 2010-2015 Petr Pavlu <setup@dagobah.cz>
4 // This file is part of CenterIM.
6 // CenterIM is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
11 // CenterIM is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with CenterIM. If not, see <http://www.gnu.org/licenses/>.
22 /// @ingroup cppconsui
34 /// Generic widget container class.
36 /// It implements @ref moveFocus "moving focus" in different @ref FocusDirection
38 class Container
: public Widget
{
40 /// Type to keep a tree of "focusable" widgets as leaves and Containers as
42 typedef tree
<Widget
*> FocusChain
;
43 enum FocusCycleScope
{
44 /// The focus does not cycle, it ends at the last widget from the focus
48 /// The focus cycles only locally.
51 /// The focus cycles also through the other container windows.
68 Container(int w
, int h
);
69 virtual ~Container() override
;
72 virtual int draw(Curses::ViewPort area
, Error
&error
) override
;
73 virtual Widget
*getFocusWidget() override
;
74 virtual void cleanFocus() override
;
75 virtual bool restoreFocus() override
;
76 virtual bool grabFocus() override
;
77 virtual void ungrabFocus() override
;
78 virtual void setParent(Container
&parent
) override
;
80 /// Adds a widget to the children list. The Container takes ownership of the
81 /// widget. It means that the widget will be deleted by the Container.
82 virtual void addWidget(Widget
&widget
, int x
, int y
);
84 /// Removes the widget from the children list and destroys it.
85 virtual void removeWidget(Widget
&widget
);
87 /// Changes logical position of the given widget to be before the position
88 /// widget. This affects focus cycling. Both passed widgets have to be
89 /// children of this Container.
90 virtual void moveWidgetBefore(Widget
&widget
, Widget
&position
);
92 /// Changes logical position of the given widget to be after the position
93 /// widget. This affects focus cycling. Both passed widgets have to be
94 /// children of this Container.
95 virtual void moveWidgetAfter(Widget
&widget
, Widget
&position
);
97 /// @todo Maybe inserting and moving of widgets should be extended. There
98 /// should be a way how to insert a widget at a specified position. Generally
99 /// insertWidget() should be made public, and MoveWidget(widget, position)
102 /// Removes (and deletes) all children widgets.
103 virtual void clear();
105 /// Returns true if the widget is visible in the current context.
106 virtual bool isWidgetVisible(const Widget
&widget
) const;
108 /// Resets the focus child by @ref cleanFocus "stealing" the focus from the
109 /// current chain and also ensures the focus goes also UP the chain to the
110 /// root widget (normally a Window).
111 virtual bool setFocusChild(Widget
&child
);
113 virtual Widget
*getFocusChild() const { return focus_child_
; }
115 /// Builds a tree of the focus chain starting from this container and puts it
116 /// into the focus_chain tree as a subtree of @ref parent.
117 virtual void getFocusChain(
118 FocusChain
&focus_chain
, FocusChain::iterator parent
);
120 /// Gives this Container information that the cached focus chain has to be
121 /// updated. If this container has a parent then this information is
122 /// propageted to it.
123 virtual void updateFocusChain();
125 /// @todo Have a return value (to see if focus was moved successfully or not)?
126 virtual void moveFocus(FocusDirection direction
);
128 virtual void setFocusCycle(FocusCycleScope scope
)
130 focus_cycle_scope_
= scope
;
132 virtual FocusCycleScope
getFocusCycle() const { return focus_cycle_scope_
; }
134 virtual void setPageFocus(bool enabled
) { page_focus_
= enabled
; }
135 virtual bool canPageFocus() const { return page_focus_
; };
137 virtual Point
getRelativePosition(
138 const Container
&ref
, const Widget
&child
) const;
139 virtual Point
getAbsolutePosition(const Widget
&child
) const;
141 virtual void onChildMoveResize(
142 Widget
&activator
, const Rect
&oldsize
, const Rect
&newsize
);
143 virtual void onChildWishSizeChange(
144 Widget
&activator
, const Size
&oldsize
, const Size
&newsize
);
145 virtual void onChildVisible(Widget
&activator
, bool visible
);
148 /// Scroll coordinates.
149 int scroll_xpos_
, scroll_ypos_
;
153 FocusCycleScope focus_cycle_scope_
;
155 /// Cached focus chain. Note: only the top container is caching the focus
157 FocusChain focus_chain_
;
159 /// Flag indicating if the cached focus chain should be updated, i.e. it
160 /// contains obsolete data.
161 bool update_focus_chain_
;
163 /// Flag indicating if fast focus changing (paging) using PageUp/PageDown keys
164 /// is allowed or not.
167 /// This defines a chain of focus. Same as
168 /// dynamic_cast<Widget *>(input_child).
169 Widget
*focus_child_
;
174 virtual void updateArea() override
;
175 virtual void updateAreaPostRealSizeChange(
176 const Size
&oldsize
, const Size
&newsize
) override
;
178 /// Sets a drawing area for a given widget.
179 virtual void updateChildArea(Widget
&child
);
181 /// Draws a single child widget.
182 virtual int drawChild(Widget
&child
, Curses::ViewPort area
, Error
&error
);
184 /// Searches children for a given widget.
185 virtual Widgets::iterator
findWidget(const Widget
&widget
);
187 /// Inserts a widget in the children list at a given position. The Container
188 /// takes ownership of the widget. It means that the widget will be deleted by
189 /// the Container. This function is intended to be used by derived classes
190 /// that needs to keep child widgets in order (see ListBox and
191 /// HorizontalListBox).
192 virtual void insertWidget(std::size_t pos
, Widget
&widget
, int x
, int y
);
194 virtual void moveWidget(Widget
&widget
, Widget
&position
, bool after
);
196 virtual void updateScroll();
197 virtual bool makePointVisible(int x
, int y
);
200 CONSUI_DISABLE_COPY(Container
);
202 void declareBindables();
205 } // namespace CppConsUI
207 #endif // CONTAINER_H
209 // vim: set tabstop=2 shiftwidth=2 textwidth=80 expandtab: