Back to index

supertuxkart  0.5+dfsg1
widget_manager.hpp
Go to the documentation of this file.
00001 //
00002 //  SuperTuxKart - a fun racing game with go-kart
00003 //  This code originally from Neverball copyright (C) 2003 Robert Kooima
00004 //
00005 //  This program is free software; you can redistribute it and/or
00006 //  modify it under the terms of the GNU General Public License
00007 //  as published by the Free Software Foundation; either version 2
00008 //  of the License, or (at your option) any later version.
00009 //
00010 //  This program is distributed in the hope that it will be useful,
00011 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 //  GNU General Public License for more details.
00014 //
00015 //  You should have received a copy of the GNU General Public License
00016 //  along with this program; if not, write to the Free Software
00017 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00018 
00019 #ifndef HEADER_WIDGET_MANAGER_H
00020 #define HEADER_WIDGET_MANAGER_H
00021 
00022 #include "widget.hpp"
00023 #include <vector>
00024 
00025 
00026 /* Big-picture instructions: the extern widget_manager is a global interface
00027  * to the class. Call add*Wgt() to insert new widgets, and change details
00028  * using the 'switch features'. By default no feature besides the one for
00029  * each widget type are enabled.
00030  *
00031  * After you defined the entire screen, call layout(), that creates and
00032  * places the widgets. Call the activated functions during the time the
00033  * widgets are alive, and make sure that update() is called each frame.
00034  *
00035  * To remove the widgets, you have to call reset().
00036  */
00037 
00038 class WidgetManager
00039 {
00040     struct WidgetID
00041     {
00042         int token;
00043         bool active; //If true, then this widget is interactive(though by
00044                        //definition, widgets are supposed to be interactive).
00045 
00046         //The percentages for the widget's rect
00047         int min_width;
00048         int min_height;
00049         int min_radius;
00050 
00051         //The last given preset scroll position is stored, to restore it in
00052         //case that the text is changed it needs to be restored.
00053         WidgetScrollPos last_preset_scroll_x;
00054         WidgetScrollPos last_preset_scroll_y;
00055 
00056         bool resize_to_text; //This has to do with layout, so it shouldn't
00057                              //inside the Widget class, even thought
00058                              //conceptually most people will asociate it with
00059                              //text
00060 
00061         Widget *widget;
00062     };
00063 
00064     enum ElementTypes
00065     {
00066         ET_WGT,
00067         ET_BREAK,
00068         ET_SWITCH //Switch orientation
00069     };
00070 
00071     /* I decided to waste one integer per break/switch with the pos
00072      * variable inside the WidgetElement struct, since otherwise we
00073      * would need 2 vectors for breaks and columns, which would use more
00074      * memory, be slower and more complex than this; another approach
00075      * is to use classes for each ElementType, but this most likely will also
00076      * waste more resources. -Coz
00077      */
00078     struct WidgetElement
00079     {
00080         ElementTypes type;
00081         int pos; //If the element is a widget, the position of the widget
00082                  //in it's vector
00083 
00084         WidgetElement(ElementTypes _type, int _pos):type(_type), pos(_pos){};
00085     };
00086 
00087     std::vector<WidgetElement> m_elems;
00088     std::vector<WidgetID> m_widgets;
00089 
00090     WidgetArea m_prev_layout_pos;
00091 
00092     int m_x;
00093     int m_y;
00094 
00095     int m_selected_wgt_token;
00096     bool m_selection_change;
00097 
00098     bool m_default_active;
00099     bool m_default_resize_to_text;
00100 
00101     bool m_default_show_rect;
00102     WidgetArea m_default_rect_round_corners;
00103     int m_default_rect_radius;
00104     const GLfloat *m_default_rect_color;
00105 
00106     bool m_default_show_border;
00107     float m_default_border_percentage;
00108     const GLfloat *m_default_border_color;
00109 
00110     bool m_default_show_texture;
00111     int m_default_texture;
00112 
00113     bool m_default_show_text;
00114     std::string m_default_text;
00115     WidgetFontSize m_default_text_size;
00116     WidgetFont m_default_font;
00117     const GLfloat* m_default_text_color;
00118 
00119     bool m_default_enable_scroll;
00120     WidgetScrollPos m_default_scroll_preset_x;
00121     WidgetScrollPos m_default_scroll_preset_y;
00122     int m_default_scroll_x_speed;
00123     int m_default_scroll_y_speed;
00124 
00125     bool m_default_enable_rotation;
00126     float m_default_rotation_angle;
00127     int m_default_rotation_speed;
00128 
00129     int m_default_show_track;
00130     int m_default_track_num;
00131 
00132     int findId(const int TOKEN) const;
00133 
00134     int calcLineWidth( const int POS );
00135     int calcLineHeight( const int POS );
00136     int calcColumnWidth( const int POS );
00137     int calcColumnHeight( const int POS );
00138 
00139     //These get* functions return the same thing as the above functions, but
00140     //they modify pos and set it to the position of the last element
00141     int getLineWidth( int& pos);
00142     int getLineHeight( int& pos );
00143     int getColumnWidth( int& pos );
00144     int getColumnHeight( int& pos );
00145 
00146     int calcLineX( const int POS );
00147     int calcColumnX( const int POS );
00148 
00149     int calcWidth();
00150     int calcHeight();
00151 
00152     bool layoutLine( int& x, int& y, int& pos );
00153     bool layoutColumn( int& x, int& y, int& pos );
00154 
00155     int findLeftWidget(const int START_WGT) const;
00156     int findRightWidget(const int START_WGT) const;
00157     int findTopWidget(const int START_WGT) const;
00158     int findBottomWidget(const int START_WGT) const;
00159 
00160        int handleFinish(const int);
00161 
00162     void setSelectedWgtToken(const int TOKEN);
00163 
00164 public:
00165     //TODO: remove return values that we don't check
00166     static const int WGT_NONE;
00167 
00168     WidgetManager();
00169     ~WidgetManager();
00170 
00171     bool isEmpty() { return m_widgets.empty(); }
00172 
00173     bool addWgt
00174     (
00175         const int TOKEN, //A number that names the widget.
00176         const int MIN_WIDTH, //These values are percentages not pixels. 100%
00177                              //is the whole screen.
00178         const int MIN_HEIGHT
00179     );
00180 
00181     bool breakLine();
00182     void switchOrder(); //This changes the orientation from horizontal to
00183                         //vertical. It's reverted at line breaks. There are
00184                         //no situations where you cannot use a switch order
00185                         //so it should always succeed.
00186 
00187     void reset();
00188 
00189     void update(const float DELTA);
00190 
00191     bool layout(); //This calls the other layout() function with the
00192                    //POSITION given to the previous call to any of the two
00193                    //layout functions. Besides the conditions under the other
00194                    //layour() function fails, itm ay also fail if no previous
00195                    //call to the layout(POSITION) function has been done.
00196     bool layout( const WidgetArea POSITION );
00197 
00198     //TODO: make all get functions const
00199     int getSelectedWgt() const { return m_selected_wgt_token; }
00200     void setSelectedWgt(const int TOKEN);
00201 
00202     //Checks if the selected widget changed since the last call to update()
00203     bool selectionChanged() const { return m_selection_change; }
00204 
00205     /* Macro functions. They are widgets with special predefined values. */
00206 
00207     //FIXME: Temporal, till I rename addWgt() to addEmptyWgt()
00208     bool addEmptyWgt(const int TOKEN, const int MIN_WIDTH, const int MIN_HEIGHT) {return addWgt(TOKEN,MIN_WIDTH,MIN_HEIGHT);}
00209 
00210     //Widget that adds visible rect & text, rounded corners with 20% radius,
00211     //sets the text, and large font
00212     bool addTitleWgt
00213     (
00214         const int TOKEN,
00215         const int MIN_WIDTH,
00216         const int MIN_HEIGHT,
00217         const std::string TEXT
00218     );
00219 
00220     //Widget that adds visible rect & text, rounded corners with 20% radius,
00221     //and sets the text
00222     bool addTextWgt
00223     (
00224         const int TOKEN,
00225         const int MIN_WIDTH,
00226         const int MIN_HEIGHT,
00227         const std::string TEXT
00228     );
00229 
00230     //Widget that adds visible rect & text, rounded corners with 20% radius,
00231     //sets the text and is selectable
00232     bool addTextButtonWgt
00233     (
00234         const int TOKEN,
00235         const int MIN_WIDTH,
00236         const int MIN_HEIGHT,
00237         const std::string TEXT
00238     );
00239 
00240     //Widget that adds visible rect & image, white rect, 5% black
00241     //border, and sets the texture
00242     bool addImgWgt
00243     (
00244         const int TOKEN,
00245         const int MIN_WIDTH,
00246         const int MIN_HEIGHT,
00247         const int IMG
00248     );
00249 
00250     bool addImgWgt
00251     (
00252         const int TOKEN,
00253         const int MIN_WIDTH,
00254         const int MIN_HEIGHT,
00255         const char* FILENAME
00256     );
00257 
00258 
00259     //Selectable widget with visible rect & image, rounded corners with 20% radius,
00260     //gray rect and texture
00261     bool addImgButtonWgt
00262     (
00263         const int TOKEN,
00264         const int MIN_WIDTH,
00265         const int MIN_HEIGHT,
00266         const int IMG
00267     );
00268 
00269     bool addImgButtonWgt
00270     (
00271         const int TOKEN,
00272         const int MIN_WIDTH,
00273         const int MIN_HEIGHT,
00274         const char* FILENAME
00275     );
00276 
00277     /* On/off widget switch features. They are all disabled/hidden initially. */
00278     void setInitialActivationState( const bool ACTIVE);
00279 
00280     void setInitialRectState
00281     (
00282         const bool SHOW,
00283         const WidgetArea ROUND_CORNERS,
00284         const int RADIUS,
00285         const GLfloat* const COLOR
00286     );
00287 
00288     void setInitialTextureState(const bool SHOW, const int TEXTURE );
00289 
00290     void setInitialBorderState
00291     (
00292         const bool SHOW,
00293         const int PERCENTAGE,
00294         const GLfloat* const COLOR
00295     );
00296 
00297     void setInitialTextState
00298     (
00299         const bool SHOW,
00300         const std::string TEXT,
00301         const WidgetFontSize SIZE,
00302         const WidgetFont FONT,
00303         const GLfloat* const COLOR,
00304         const bool RESIZE_WGT
00305     );
00306 
00307     void setInitialScrollState
00308     (
00309         const bool ENABLE,
00310         const WidgetScrollPos X_POS,
00311         const WidgetScrollPos Y_POS,
00312         const int X_SPEED,
00313         const int Y_SPEED
00314     );
00315 
00316     void setInitialRotationState
00317     (
00318         const bool ENABLE,
00319         const float ANGLE,
00320         const int SPEED
00321     );
00322 
00323 
00324     void setInitialTrackState
00325     (
00326         const bool SHOW,
00327         const int TRACK
00328     );
00329 
00330     void restoreDefaultStates();
00331 
00332     void activateWgt(const int TOKEN);
00333     void deactivateWgt(const int TOKEN);
00334 
00335     //FIXME: maybe this should be setWgtRectColor ? and put after the other rect funcs?
00336     void setWgtColor(const int TOKEN, const GLfloat* const COLOR);
00337     void setWgtRoundCorners(const int TOKEN, const WidgetArea CORNERS);
00338     //The radius given is the percentage of the height or the width of the
00339     //widget, whatever is smaller; however, the maximum is 50% (the corner's
00340     //size).
00341     void setWgtCornerRadius(const int TOKEN, const int RADIUS);
00342     void showWgtRect(const int TOKEN);
00343     void hideWgtRect(const int TOKEN);
00344 
00345     void setWgtBorderColor(const int TOKEN, const GLfloat* const COLOR);
00346     void setWgtBorderPercentage(const int TOKEN, const int PERCENTAGE);
00347     void showWgtBorder(const int TOKEN);
00348     void hideWgtBorder(const int TOKEN);
00349     //TODO: add initial border colors, if I don't erase those functions.
00350 
00351     void setWgtTexture(const int TOKEN, const int TEXTURE);
00352     void setWgtTexture(const int TOKEN, const char* FILENAME, const bool is_full_path=true);
00353     void showWgtTexture(const int TOKEN);
00354     void hideWgtTexture(const int TOKEN);
00355 
00356     void setWgtText( const int TOKEN, const char* TEXT );
00357     void setWgtText( const int TOKEN, const std::string TEXT );
00358     void setWgtTextSize( const int TOKEN, const WidgetFontSize SIZE );
00359     void setWgtFont( const int TOKEN, const WidgetFont FONT );
00360     void setWgtTextColor( const int TOKEN, const GLfloat* const COLOR );
00361     void setWgtResizeToText( const int TOKEN, const bool RESIZE );
00362     void showWgtText( const int TOKEN );
00363     void hideWgtText( const int TOKEN );
00364     void resizeWgtToText( const int TOKEN );
00365     void reloadFonts();
00366 
00367     //FIXME: change to enableWgtScrolling, since it enables or disables
00368     //FIXME: maybe all that enabling the scrolling should do, is to allow
00369     //players to lower/raise it?
00370     //only the scrolling movement, not setting the scrolling position.
00371     void enableWgtScroll( const int TOKEN );
00372     void disableWgtScroll( const int TOKEN );
00373     void setWgtXScrollPos( const int TOKEN, const WidgetScrollPos POS );
00374     void setWgtYScrollPos( const int TOKEN, const WidgetScrollPos POS );
00375     void setWgtXScrollSpeed( const int TOKEN, const int SPEED );
00376     void setWgtYScrollSpeed( const int TOKEN, const int SPEED );
00377 
00378     void enableWgtRotation( const int TOKEN );
00379     void disableWgtRotation( const int TOKEN );
00380     void setWgtRotationAngle( const int TOKEN, const float ANGLE );
00381     void setWgtRotationSpeed( const int TOKEN, const int SPEED );
00382 
00383     void showWgtTrack( const int TOKEN );
00384     void hideWgtTrack( const int TOKEN );
00385     void setWgtTrackNum( const int TOKEN, const int TRACK );
00386 
00387     /* Activated widget features. */
00388     void pulseWgt( const int TOKEN ) const;
00389 
00390     /* Convenience widget functions. */
00391     void lightenWgtColor(const int TOKEN);
00392     void darkenWgtColor(const int TOKEN);
00393 
00394     /* Input device handling. */
00395     int handlePointer( const int X, const int Y );
00396     int handleLeft();
00397     int handleRight();
00398     int handleUp();
00399     int handleDown();
00400 
00401        /* Scrolling modification. */
00402        void increaseScrollSpeed(bool = false);
00403        void decreaseScrollSpeed(bool = false);
00404 };
00405 
00406 extern WidgetManager *widget_manager;
00407 
00408 #endif
00409 
00410 /* EOF */