gui/widgets/scrollbar_container.hpp

Go to the documentation of this file.
00001 /* $Id: scrollbar_container.hpp 54007 2012-04-28 19:16:10Z mordante $ */
00002 /*
00003    Copyright (C) 2008 - 2012 by Mark de Wever <koraq@xs4all.nl>
00004    Part of the Battle for Wesnoth Project http://www.wesnoth.org/
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY.
00012 
00013    See the COPYING file for more details.
00014 */
00015 
00016 #ifndef GUI_WIDGETS_SCROLLBAR_CONTAINER_HPP_INCLUDED
00017 #define GUI_WIDGETS_SCROLLBAR_CONTAINER_HPP_INCLUDED
00018 
00019 #include "gui/auxiliary/notifiee.hpp"
00020 #include "gui/widgets/container.hpp"
00021 #include "gui/widgets/scrollbar.hpp"
00022 
00023 namespace gui2 {
00024 
00025 class tspacer;
00026 
00027 namespace implementation {
00028     struct tbuilder_scroll_label;
00029     struct tbuilder_scrollbar_panel;
00030 }
00031 
00032 /**
00033  * Base class for creating containers with one or two scrollbar(s).
00034  *
00035  * For now users can't instanciate this class directly and needs to use small
00036  * wrapper classes. Maybe in the future users can use the class directly.
00037  *
00038  * @todo events are not yet send to the content grid.
00039  */
00040 class tscrollbar_container
00041     : public tcontainer_
00042 {
00043     friend class tdebug_layout_graph;
00044 
00045     friend struct implementation::tbuilder_scroll_label;
00046     friend struct implementation::tbuilder_scrollbar_panel;
00047 #ifndef GUI2_EXPERIMENTAL_LISTBOX
00048     friend class tlistbox;
00049 #endif
00050     friend class ttree_view;
00051     friend struct tscrollbar_container_implementation;
00052 
00053 public:
00054 
00055     explicit tscrollbar_container(const unsigned canvas_count);
00056 
00057     ~tscrollbar_container() { delete content_grid_; }
00058 
00059     /** The way to handle the showing or hiding of the scrollbar. */
00060     enum tscrollbar_mode {
00061         always_visible,           /**<
00062                                    * The scrollbar is always shown, whether
00063                                    * needed or not.
00064                                    */
00065         always_invisible,         /**<
00066                                    * The scrollbar is never shown even not
00067                                    * when needed. There's also no space
00068                                    * reserved for the scrollbar.
00069                                    */
00070         auto_visible,             /**<
00071                                    * The scrollbar is shown when the number of
00072                                    * items is larger as the visible items. The
00073                                    * space for the scrollbar is always
00074                                    * reserved, just in case it's needed after
00075                                    * the initial sizing (due to adding items).
00076                                    */
00077         auto_visible_first_run    /**<
00078                                    * Like auto_visible, but when not needed
00079                                    * upon the initial layout phase, the bars
00080                                    * are not shown and no space is reserved
00081                                    * for them. (The algorithm hides them by
00082                                    * default.
00083                                    */
00084     };
00085 
00086     /***** ***** ***** ***** layout functions ***** ***** ***** *****/
00087 
00088     /** Inherited from tcontainer_. */
00089     void layout_init(const bool full_initialization);
00090 
00091     /** Inherited from twidget. */
00092     void request_reduce_height(const unsigned maximum_height);
00093 
00094     /** Inherited from tcontrol. */
00095     void request_reduce_width(const unsigned maximum_width);
00096 
00097     /** Inherited from tcontainer_. */
00098     bool can_wrap() const
00099     {
00100         // Note this function is called before the object is finalized.
00101         return content_grid_
00102             ? content_grid_->can_wrap()
00103             : false;
00104     }
00105 
00106 private:
00107     /** Inherited from tcontainer_. */
00108     tpoint calculate_best_size() const;
00109 public:
00110 
00111     /** Inherited from tcontainer_. */
00112     void place(const tpoint& origin, const tpoint& size);
00113 
00114     /** Inherited from tcontainer_. */
00115     void set_origin(const tpoint& origin);
00116 
00117     /** Inherited from tcontainer_. */
00118     void set_visible_area(const SDL_Rect& area);
00119 
00120     /***** ***** ***** inherited ****** *****/
00121 
00122     /** Inherited from tcontainer_. */
00123     bool get_active() const { return state_ != DISABLED; }
00124 
00125     /** Inherited from tcontainer_. */
00126     unsigned get_state() const { return state_; }
00127 
00128     /** Inherited from tcontainer_. */
00129     twidget* find_at(const tpoint& coordinate, const bool must_be_active);
00130 
00131     /** Inherited from tcontainer_. */
00132     const twidget* find_at(const tpoint& coordinate,
00133             const bool must_be_active) const;
00134 
00135     /** Inherited from tcontainer_. */
00136     twidget* find(const std::string& id, const bool must_be_active);
00137 
00138     /** Inherited from tcontrol.*/
00139     const twidget* find(const std::string& id, const bool must_be_active) const;
00140 
00141     /** Inherited from tcontainer_. */
00142     bool disable_click_dismiss() const;
00143 
00144     /***** ***** ***** setters / getters for members ***** ****** *****/
00145 
00146     /** @note shouldn't be called after being shown in a dialog. */
00147     void set_vertical_scrollbar_mode(const tscrollbar_mode scrollbar_mode);
00148     tscrollbar_mode get_vertical_scrollbar_mode() const
00149         { return vertical_scrollbar_mode_; }
00150 
00151     /** @note shouldn't be called after being shown in a dialog. */
00152     void set_horizontal_scrollbar_mode(const tscrollbar_mode scrollbar_mode);
00153     tscrollbar_mode get_horizontal_scrollbar_mode() const
00154         { return horizontal_scrollbar_mode_; }
00155 
00156     tgrid *content_grid() { return content_grid_; }
00157     const tgrid *content_grid() const { return content_grid_; }
00158 
00159     const SDL_Rect& content_visible_area() const
00160         { return content_visible_area_; }
00161 
00162     /***** ***** ***** scrollbar helpers ***** ****** *****/
00163 
00164     /**
00165      * Scrolls the vertical scrollbar.
00166      *
00167      * @param scroll              The position to scroll to.
00168      */
00169     void scroll_vertical_scrollbar(const tscrollbar_::tscroll scroll);
00170 
00171     /**
00172      * Scrolls the horizontal scrollbar.
00173      *
00174      * @param scroll              The position to scroll to.
00175      */
00176     void scroll_horizontal_scrollbar(const tscrollbar_::tscroll scroll);
00177 
00178     /**
00179      * Callback when the scrollbar moves (NOTE maybe only one callback needed).
00180      * Maybe also make protected or private and add a friend.
00181      */
00182     void vertical_scrollbar_moved()
00183         { scrollbar_moved(); }
00184 
00185     void horizontal_scrollbar_moved()
00186         { scrollbar_moved(); }
00187 
00188 protected:
00189 
00190     /**
00191      * Shows a certain part of the content.
00192      *
00193      * When the part to be shown is bigger as the visible viewport the top
00194      * left of the wanted rect will be the top left of the viewport.
00195      *
00196      * @param rect                The rect which should be visible.
00197      */
00198     void show_content_rect(const SDL_Rect& rect);
00199 
00200     /*
00201      * The widget contains the following three grids.
00202      *
00203      * * _vertical_scrollbar_grid containing at least a widget named
00204      *   _vertical_scrollbar
00205      *
00206      * * _horizontal_scrollbar_grid containing at least a widget named
00207      *   _horizontal_scrollbar
00208      *
00209      * * _content_grid a grid which holds the contents of the area.
00210      *
00211      * NOTE maybe just hardcode these in the finalize phase...
00212      *
00213      */
00214 
00215     /**
00216      * Sets the status of the scrollbar buttons.
00217      *
00218      * This is needed after the scrollbar moves so the status of the buttons
00219      * will be active or inactive as needed.
00220      */
00221     void set_scrollbar_button_status();
00222 
00223     /**
00224      * Notification if the content of a child needs a resize.
00225      *
00226      * When a resize is required the container first can try to handle it
00227      * itself. If it can't honour the request the function will call @ref
00228      * twindow::invalidate_layout().
00229      *
00230      * @note Calling this function on a widget with size == (0, 0) results
00231      * false but doesn't call invalidate_layout, the engine expects to be in
00232      * build up phase with the layout already invalidated.
00233      *
00234      * @param force_sizing        If the contents fit do we want to force a
00235      *                            resize? This is needed in the MP lobby since
00236      *                            items might not be properly placed yet.
00237      *                            (The listboxes with the player info need it.)
00238      *
00239      * @returns                   True if the resize is handled, false
00240      *                            otherwise.
00241      */
00242     bool content_resize_request(const bool force_sizing = false);
00243 
00244     /**
00245      * Request from the content to modify the size of the container.
00246      *
00247      * When the wanted resize fails the function will call @ref
00248      * twindow::invalidate_layout().
00249      *
00250      *
00251      * @note Calling this function on a widget with size == (0, 0) results
00252      * false but doesn't call invalidate_layout, the engine expects to be in
00253      * build up phase with the layout already invalidated.
00254      *
00255      * @note If @ref twindow::get_need_layout() is true the function returns
00256      * false and doesn't try to fit the contents since a layout phase will be
00257      * triggered anyway.
00258      *
00259      * @note This function might replace the @ref content_resize_request above.
00260      *
00261      * @param width_modification  The wanted modification to the width:
00262      *                            * negative values reduce width.
00263      *                            * zero leave width as is.
00264      *                            * positive values increase width.
00265      * @param height_modification The wanted modification to the height:
00266      *                            * negative values reduce height.
00267      *                            * zero leave height as is.
00268      *                            * positive values increase height.
00269      *
00270      * @returns                   True is wanted modification is accepted false
00271      *                            otherwise.
00272      */
00273     bool content_resize_request(
00274               const int width_modification
00275             , const int height_modification);
00276 
00277 private:
00278 
00279     /**
00280      * Helper for @ref content_resize_request.
00281      *
00282      * Handle the width modification.
00283      */
00284     bool content_resize_width(const int width_modification);
00285 
00286     /**
00287      * Helper for @ref content_resize_request.
00288      *
00289      * Handle the height modification.
00290      */
00291     bool content_resize_height(const int height_modification);
00292 
00293 protected:
00294 
00295     /***** ***** ***** ***** keyboard functions ***** ***** ***** *****/
00296 
00297     /**
00298      * Home key pressed.
00299      *
00300      * @param modifier            The SDL keyboard modifier when the key was
00301      *                            pressed.
00302      * @param handled             If the function handles the key it should
00303      *                            set handled to true else do not modify it.
00304      *                            This is used in the keyboard event
00305      *                            changing.
00306      */
00307     virtual void handle_key_home(SDLMod modifier, bool& handled);
00308 
00309     /**
00310      * End key pressed.
00311      *
00312      * @param modifier            The SDL keyboard modifier when the key was
00313      *                            pressed.
00314      * @param handled             If the function handles the key it should
00315      *                            set handled to true else do not modify it.
00316      *                            This is used in the keyboard event
00317      *                            changing.
00318      */
00319     virtual void handle_key_end(SDLMod modifier, bool& handled);
00320 
00321     /**
00322      * Page up key pressed.
00323      *
00324      * @param modifier            The SDL keyboard modifier when the key was
00325      *                            pressed.
00326      * @param handled             If the function handles the key it should
00327      *                            set handled to true else do not modify it.
00328      *                            This is used in the keyboard event
00329      *                            changing.
00330      */
00331     virtual void handle_key_page_up(SDLMod modifier, bool& handled);
00332 
00333     /**
00334      * Page down key pressed.
00335      *
00336      * @param modifier            The SDL keyboard modifier when the key was
00337      *                            pressed.
00338      * @param handled             If the function handles the key it should
00339      *                            set handled to true else do not modify it.
00340      *                            This is used in the keyboard event
00341      *                            changing.
00342      */
00343     virtual void handle_key_page_down(SDLMod modifier, bool& handled);
00344 
00345 
00346     /**
00347      * Up arrow key pressed.
00348      *
00349      * @param modifier            The SDL keyboard modifier when the key was
00350      *                            pressed.
00351      * @param handled             If the function handles the key it should
00352      *                            set handled to true else do not modify it.
00353      *                            This is used in the keyboard event
00354      *                            changing.
00355      */
00356     virtual void handle_key_up_arrow(SDLMod modifier, bool& handled);
00357 
00358     /**
00359      * Down arrow key pressed.
00360      *
00361      * @param modifier            The SDL keyboard modifier when the key was
00362      *                            pressed.
00363      * @param handled             If the function handles the key it should
00364      *                            set handled to true else do not modify it.
00365      *                            This is used in the keyboard event
00366      *                            changing.
00367      */
00368     virtual void handle_key_down_arrow(SDLMod modifier, bool& handled);
00369 
00370     /**
00371      * Left arrow key pressed.
00372      *
00373      * @param modifier            The SDL keyboard modifier when the key was
00374      *                            pressed.
00375      * @param handled             If the function handles the key it should
00376      *                            set handled to true else do not modify it.
00377      *                            This is used in the keyboard event
00378      *                            changing.
00379      */
00380     virtual void handle_key_left_arrow(SDLMod modifier, bool& handled);
00381 
00382     /**
00383      * Right arrow key pressed.
00384      *
00385      * @param modifier            The SDL keyboard modifier when the key was
00386      *                            pressed.
00387      * @param handled             If the function handles the key it should
00388      *                            set handled to true else do not modify it.
00389      *                            This is used in the keyboard event
00390      *                            changing.
00391      */
00392     virtual void handle_key_right_arrow(SDLMod modifier, bool& handled);
00393 private:
00394 
00395     /**
00396      * Possible states of the widget.
00397      *
00398      * Note the order of the states must be the same as defined in settings.hpp.
00399      */
00400     enum tstate { ENABLED, DISABLED, COUNT };
00401 
00402     /**
00403      * Current state of the widget.
00404      *
00405      * The state of the widget determines what to render and how the widget
00406      * reacts to certain 'events'.
00407      */
00408     tstate state_;
00409 
00410     /**
00411      * The mode of how to show the scrollbar.
00412      *
00413      * This value should only be modified before showing, doing it while
00414      * showing results in UB.
00415      */
00416     tscrollbar_mode
00417         vertical_scrollbar_mode_,
00418         horizontal_scrollbar_mode_;
00419 
00420     /** These are valid after finalize_setup(). */
00421     tgrid
00422         *vertical_scrollbar_grid_,
00423         *horizontal_scrollbar_grid_;
00424 
00425     /** These are valid after finalize_setup(). */
00426     tscrollbar_
00427         *vertical_scrollbar_,
00428         *horizontal_scrollbar_;
00429 
00430     /** The grid that holds the content. */
00431     tgrid *content_grid_;
00432 
00433     /** Dummy spacer to hold the contents location. */
00434     tspacer *content_;
00435 
00436     /**
00437      * Cache for the visible area for the content.
00438      *
00439      * The visible area for the content needs to be updated when scrolling.
00440      */
00441     SDL_Rect content_visible_area_;
00442 
00443     /** The builder needs to call us so we do our setup. */
00444     void finalize_setup(); // FIXME make protected
00445 
00446     /**
00447      * Function for the subclasses to do their setup.
00448      *
00449      * This function is called at the end of finalize_setup().
00450      */
00451     virtual void finalize_subclass() {}
00452 
00453     /** Inherited from tcontainer_. */
00454     void layout_children();
00455 
00456     /** Inherited from tcontainer_. */
00457     void impl_draw_children(surface& frame_buffer);
00458     void impl_draw_children(surface& frame_buffer, int x_offset, int y_offset);
00459 
00460     /** Inherited from tcontainer_. */
00461     void child_populate_dirty_list(twindow& caller,
00462         const std::vector<twidget*>& call_stack);
00463 
00464     /**
00465      * Sets the size of the content grid.
00466      *
00467      * This function normally just updates the content grid but can be
00468      * overridden by a subclass.
00469      *
00470      * @param origin              The origin for the content.
00471      * @param size                The size of the content.
00472      */
00473     virtual void set_content_size(const tpoint& origin, const tpoint& size);
00474 
00475     /** Helper function which needs to be called after the scollbar moved. */
00476     void scrollbar_moved();
00477 
00478     /** Inherited from tcontrol. */
00479     const std::string& get_control_type() const;
00480 
00481     /***** ***** ***** signal handlers ***** ****** *****/
00482 
00483     void signal_handler_sdl_key_down(const event::tevent event
00484             , bool& handled
00485             , const SDLKey key
00486             , SDLMod modifier);
00487 
00488     void signal_handler_sdl_wheel_up(const event::tevent event
00489             , bool& handled);
00490     void signal_handler_sdl_wheel_down(const event::tevent event
00491             , bool& handled);
00492     void signal_handler_sdl_wheel_left(const event::tevent event
00493             , bool& handled);
00494     void signal_handler_sdl_wheel_right(const event::tevent event
00495             , bool& handled);
00496 };
00497 
00498 } // namespace gui2
00499 
00500 #endif
00501 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by doxygen 1.7.1 on Fri May 25 2012 01:02:59 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs