Main Page | Namespace List | Class Hierarchy | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

CSGrafikElement.h

Go to the documentation of this file.
00001 // USES SDL_Surface
00002 // USES SDL_Rect 
00003 
00004 #ifndef CSGRAFIK_ELEMENT_h
00005 #define CSGRAFIK_ELEMENT_h
00006 
00007 #ifdef WIN32
00008 #pragma warning(disable : 4786 )
00009 #endif
00010 
00011 const int BORDER_STATE_VISIBLE = 1;
00012 const int BORDER_STATE_PRESSED = 2;
00013 const int BORDER_STATE_HOVERING = 4;
00014 const int BORDER_STATE_FOCUSED = 8;
00015 const int BORDER_STATE_ACTIVATED = 16;
00016 const int BORDER_STATE_ENABLED = 32;
00017 
00018 const int BORDER_STATE_DEFAULT = BORDER_STATE_VISIBLE;
00019 
00020 // General GUI constant definitions
00021 const int BUTTON_VISIBLE =      BORDER_STATE_VISIBLE;   //!< Button state -> pressed
00022 const int BUTTON_PRESSED =      BORDER_STATE_PRESSED;   //!< Button state -> pressed
00023 const int BUTTON_HOVERING =     BORDER_STATE_HOVERING;  //!< Button state -> hovering (unpressed) (implemented in \a CSMenu)
00024 const int BUTTON_FOCUSED =      BORDER_STATE_FOCUSED;   //!< Button state -> focused (unpressed) (not done yet)
00025 const int BUTTON_ACTIVATED =    BORDER_STATE_ACTIVATED; //!< Button state -> activated (unpressed) (not done yet)
00026 const int BUTTON_ENABLED =      BORDER_STATE_ENABLED;   //!< Button state -> disabled (unpressed) (not done yet)
00027 
00028 const int BUTTON_DEFAULT =      BUTTON_VISIBLE + BUTTON_ENABLED;    //!< Button state -> unpressed
00029 
00030 const int POSITION_NOT_SET = -1;//!< positon information is not given
00031 const int POSITION_NORTH = 0;   //!< positon NORTH, item is placed above the element with the smallest y - pos value
00032 const int POSITION_SOUTH = 1;   //!< positon SOUTH, item is placed below the element with the greatest y - pos value
00033 const int POSITION_EAST = 2;    //!< positon EAST, item is placed left the element with the greatest x - pos value
00034 const int POSITION_WEST = 3;    //!< positon WEST, item is placed right the element with the smallest y - pos value
00035 const int POSITION_CENTER = 4;  //!< positon CENTER, makes only sense if component is autosizing both x and y
00036 const int POSITION_ABSOLUT = 5; //!< not used
00037 
00038 //! same as directions, if changed to something unique, one must add a nonViewported special case in buildArea() in LayoutManager!
00039 const int POSITION_ORDER_TOP    = POSITION_NORTH; //!< same as POSITION_NORTH
00040 const int POSITION_ORDER_BOTTOM = POSITION_SOUTH; //!< same as POSITION_SOUTH
00041 const int POSITION_ORDER_LEFT   = POSITION_WEST;  //!< same as POSITION_WEST
00042 const int POSITION_ORDER_RIGHT  = POSITION_EAST;  //!< same as POSITION_EAST
00043 
00044 const int TYPE_HORIZONTAL = 0;  //!< element is arranged horizontal
00045 const int TYPE_VERTICAL = 1;    //!< element is arranged vertical
00046 
00047 const int TYPE_CHANGE_UP = 1;   
00048 const int TYPE_CHANGE_INIT = 2;
00049 const int TYPE_CHANGE_DOWN = -1;
00050 const int TYPE_CHANGE_ONLY_ME = -2;
00051 
00052 const int LAYOUT_ELEMENT = 1;   // add remove visibility
00053 const int LAYOUT_INTERNAL = 8;  // font, border, area... changed
00054 const int LAYOUT_LAYOUT = 16;   // layourt changed
00055 const int LAYOUT_MOVE = 2;
00056 const int LAYOUT_SIZE = 4;
00057 const int LAYOUT_NOT = 0;
00058 
00059 #include <vector>
00060 #include <string>
00061 
00062 #include "SDLMain.h"
00063 #include "CSMessageListener.h"
00064 #include "CSLAF.h"
00065 #include "CSLog.h"
00066 #include "CSLayoutManager.h "
00067 #include "CSInset.h"
00068 
00069 class CSGrafikElement;
00070 class CSFont;
00071 class CSBorder;
00072 class CSDesktop;
00073 class CSWindow;
00074 class CSScrollbar;
00075 class CSArea;
00076 class CSLayoutManager;
00077 
00078 typedef std::vector<CSGrafikElement *> CSGrafikElements;
00079 
00080 const int MOUSE_CURSOR_TYPE_DEFAULT = 0;
00081 const int MOUSE_CURSOR_TYPE_SIZING = 1;
00082 
00083 /**
00084     This is the base class of all GUI elements.
00085     All GUI elements are derived from this class.
00086     The "base" class at runtime is the CSDesktop class. To a desktop all Gui 
00087     elements are added (or to its children).
00088 
00089     The GUI elements are event driven (as almost all GUI's are). The events are
00090     dispatched from the desktop. The desktop itself gets "hardware" events (in this
00091     case SDL events) from outside (simple method calls). 
00092 
00093     Within this set of classes the events are generated at runtime from the 
00094     CSGame class, which "polls" SDL every "game round".
00095 
00096     Events are send to listeners. One can simply add a listener with the "addlistener" method.
00097 
00098     C++ does not per default have (java has that!) the ability to call a super() method.
00099     (a method that is overloaded by a child method)
00100 
00101     With event passing and wanting a default behaviour for all classes, a strategy (convention)
00102     was used within the gui classes, that allows us to call the parents overloaded 
00103     methods from the child.
00104     
00105     The default method to wait for events is:
00106     <PRE>
00107         reactOnMessage(...)
00108     </PRE>
00109     
00110     That method is virtual and therefor overloadable.
00111     Each Gui-element overloads this method.
00112 
00113     BUT:
00114 
00115     Each element also implements a method (non virtual, protected or public)
00116     <PRE>
00117         reactOnMessage"ElementName"(...)
00118     </PRE>
00119 
00120     The "reactOnMessage()" allway! only calls the element based method. Therefor
00121     each child can also call (all) the parent methods!
00122 
00123     e.g.
00124     CSButton implements following methods:
00125 
00126     <PRE>
00127         void reactOnMessageDragButton(CSMessage *message);
00128         virtual void reactOnMessage(CSMessage *message);
00129     </PRE>
00130 
00131     the bodies might look like:
00132 
00133     <PRE>
00134         void CSButton::reactOnMessage(CSMessage *message)
00135         {
00136             reactOnMessageButton(message);
00137         }
00138 
00139         void CSButton::reactOnMessageButton(CSMessage *message)
00140         {
00141             static char *functionName="reactOnMessage";
00142             if (message->mIsHandled)
00143             {
00144                 reactOnMessageGrafikElement(message);
00145                 return;
00146             }
00147             ... handle events
00148             reactOnMessageGrafikElement(message);
00149         }
00150     </PRE>
00151 
00152     Thus the parent methods are allways called, and can still
00153     handle events not handled by the subclass.
00154     (This can even be used further - see e.g. MenuItems...)
00155 
00156     
00157     This class implements the basic methods all gui classes need.
00158     Child classes must overload the paint(destination) method to display themselves.
00159    
00160     All GrafikElements can be added to another GrafikElement. (But not everything makes sense - 
00161     like adding a desktop to a window...)
00162     The strukture should be like: 
00163     <PRE>
00164             Screen-> Desktop->Window->Elements (like Label, Button, Textfiled)
00165     </PRE>
00166   */
00167 class CSGrafikElement : public CSMessageDispatchable, public CSMessageListener
00168 {
00169     friend CSDesktop;           // because it does a modal Desktop "painting"
00170     friend CSLayoutManager;         
00171     friend CSWindow;            // for getElements
00172     private:
00173         CSLayoutManager *mLayoutManager;
00174         CSLayoutData mLayoutData;
00175         bool mFrontElement;
00176         bool mLayoutChanged;
00177 
00178         CSGrafikElement *mMainElement;
00179         int mX;                 //!< Position in parent
00180         int mY;                 //!< Position in parent
00181         int mViewportX;         //!< "physical" start of the viewport within this element (if there is viewport)
00182         int mViewportY;         //!< "physical" start of the viewport within this element (if there is viewport)
00183         int mViewportHeight;    //!< "physical" Dimension of viewport
00184         int mViewportWidth;     //!< "physical" Dimension of viewport
00185         int mViewportOffsetX;   //!< where the viewport starts displaying the childElements!
00186         int mViewportOffsetY;   //!< where the viewport starts displaying the childElements!
00187         SDL_Rect mElementArea;  //!< mX, mY, mHeight, mWidth (for easier updating)
00188         SDL_Rect mViewportArea; //!< mViewportX, mViewportY, mViewportHeight, mViewportWidth (for easier updating)
00189         int getElementMaxX();
00190         int getElementMaxY();
00191         //! not deleting, no listener removed!, only removing!
00192         void removeMainAllElements() {mElements.clear(); }      
00193         CSGrafikElement *getElement(int x, int y, SDL_Rect *parentViewport, int &receiverX, int &receiverY); //!< get (sub-) element, that is at the given (screen) coordinates 
00194         CSGrafikElements *getElements() {return &mElements; }//!<  this returns the "real thing - do not change!
00195         
00196         bool mFocusable;        //!< can this element receive the focus of a desktop?
00197 
00198         bool mFocused;          //!< is this element in focus of a desktop?
00199         bool mModal;            //!< is this element modal (makes sense only for windows)
00200         bool mEnabled;
00201         bool mActivated;
00202         bool mActive;
00203 
00204         bool mBackGroundColorSet;   //!< if background color is set from outside, even after a layout(), the once set color is used
00205         int mBackgroundColor;       //!< Background color of component
00206         bool mTextColorSet;         //!< if text color is set from outside, even after a layout(), the once set color is used
00207         int mTextColor;             //!< Text color of component
00208         bool mHorizontalElementSpacingSet;
00209         int mHorizontalElementSpacing;
00210         bool mVerticalElementSpacingSet;
00211         int mVerticalElementSpacing;
00212 
00213         int mCurrentLAFId;      //!< currently ID of the LAF in use
00214         int mCursorType;        //!< what kind of mouse cursor should the cursor, when over this element?
00215 
00216         CSBorder *mBorder;      //!< the currently set CSBorder
00217         CSArea *mArea;
00218         CSFont *mFont;          //!< the currently set CSFont
00219         int mStyle;
00220         std::string mType;
00221 
00222     protected:
00223         bool mVisible;          //!< is this element visible?
00224         CSInset mInset;         //!< the currently set CSInset
00225         CSInset *getInsetInternal() {return &mInset;}
00226         CSLayoutData *getLayoutDataInternal() {return &mLayoutData;} ///< pointer is faster, but more dangerous
00227 
00228         void deleteElements();
00229         virtual int getViewportWidth() {return mViewportWidth;} //!< Width that elements, that are added to this component can use
00230         virtual int getViewportHeight() {return mViewportHeight;}   //!< Height that elements, that are added to this component can use
00231         virtual int getViewportX() {return mViewportX;} //!< Coordinates in relation to this element, 0,0 is left upper corner
00232         virtual int getViewportY() {return mViewportY;} //!< 
00233         
00234         
00235         int mBorderState;
00236         bool mHeightSet;        //!< was height of component set from outside
00237         bool mWidthSet;         //!< was width of component set from outside
00238         int mHeight;            //!< "physical" Dimension of component (as is seen by parent)
00239         int mWidth;             //!< "physical" Dimension of component (as is seen by parent)
00240         int mMinWidth;          //!< without border, without spacing
00241         int mMinHeight;         //!< without border, without spacing
00242 
00243         int mActionId;          //!< the action id (if there is one) of an element (e.g Button)
00244 
00245 
00246         CSGrafikElements mElements; //!< all child elements are stored here
00247         CSGrafikElement *mParent;   //!< the direct parent (if any) is stored here
00248 
00249         std::string mTooltipText;   // text of tooltip (default "")
00250 
00251         GuiMessage MESSAGE_FOCUS_GAINED;    //!< Message that can be sent from CS Graphic element (CSDesktop)
00252         GuiMessage MESSAGE_FOCUS_LOST;      //!< Message that can be sent from CS Graphic element (CSDesktop)
00253         GuiMessage MESSAGE_KEY_PRESSED;     //!< Message that can be sent from CS Graphic element (CSDesktop)
00254         GuiMessage MESSAGE_KEY_RELEASED;    //!< Message that can be sent from CS Graphic element (CSDesktop)
00255         GuiMessage MESSAGE_MOUSE_PRESSED;   //!< Message that can be sent from CS Graphic element (CSDesktop)
00256         GuiMessage MESSAGE_MOUSE_RELEASED;  //!< Message that can be sent from CS Graphic element (CSDesktop)
00257         GuiMessage MESSAGE_MOUSE_MOTION;    //!< Message that can be sent from CS Graphic element (CSDesktop)
00258         GuiMessage MESSAGE_MOUSE_MOTION_LOST;   //!< Message that can be sent from CS Graphic element (CSDesktop)
00259 
00260         SDL_Rect getElementArea() {return mElementArea;}
00261 
00262 
00263         //! Set the parent element of this
00264         virtual void setParent(CSGrafikElement *parent);
00265         void init(int height, int width);       //!< initializes this element, called once from constructor
00266         //! Translates the given element coordinates to Desktop coordinates
00267         void translateToDesktop(int &x, int &y);
00268         //! Builds the viewport sizes from \a mHeight and \a mWidth (and sets the rectangles)
00269         // void buildArea();
00270         virtual void CSGrafikElement::paintArea(SDL_Surface *destination, SDL_Rect *parentArea)
00271         {
00272             paintAreaStandard(destination, parentArea);
00273         }
00274         void paintBorder(SDL_Surface *destination, SDL_Rect *parentArea);
00275         void paintAreaStandard(SDL_Surface *destination, SDL_Rect *parentArea);
00276         void paintChildren(SDL_Surface *destination, SDL_Rect *parentViewport); 
00277         CSGrafikElement *removeMainElement(CSGrafikElement *element);
00278         CSLayoutManager *getMainLayoutManager()
00279         {
00280             return mLayoutManager;
00281         }
00282 
00283         void setMainLayoutManager(CSLayoutManager *manager)
00284         {
00285             if (mLayoutManager != 0)
00286             {
00287                 delete mLayoutManager;
00288                 mLayoutManager = 0;
00289             }
00290             mLayoutManager = manager;
00291             if (mLayoutManager != 0)
00292             {
00293                 mLayoutManager->setHostingElement(this);
00294             }
00295         }
00296 
00297         virtual void rebuildElement() {} // if a component is made up of elements dependend of LAF, than this method is called
00298                                  // during a lafChanged, so element can be changed (like Icons...)
00299         // protected, so desktop can call it befor painting
00300         void doLayout();    // return negative -> parentChangerelevant, positive -> children relevant
00301         void setMainElement(CSGrafikElement *element) {mMainElement = element;}
00302     
00303     public:
00304         static const char *CLASS;               ///< static element, name of this class (introsepection)
00305         virtual std::string getType() {return (std::string) CLASS;}
00306 
00307         CSGrafikElement(int height, int width);
00308         ~CSGrafikElement(void);
00309         CSGrafikElement *getUppermostAncestor();
00310         CSWindow *getParentWindow();
00311         CSDesktop *getDesktop(void);                ///< get the next parent, that is a CSDesktop (or null)
00312         CSGrafikElement *getParent(void) {return mParent;}
00313         virtual void paint(SDL_Surface *destination, SDL_Rect *parentViewport)
00314         {
00315             paintChildren(destination, parentViewport);
00316         }
00317         void setPosition(int x, int y);         ///< set X, Y coordinates in relation to parent (useaable Area)
00318         bool isFrontElement() {return mFrontElement;}
00319         void toFront(CSGrafikElement *element);
00320         void setGUIType(std::string type) {mType = type;}
00321         std::string getGUIType() {if (mType.size() == 0) return getType(); return mType;}
00322         int getX() {return mX;}                 ///< X coordinates in relation to parent
00323         int getY() {return mY;}                 ///< Y coordinates in relation to parent
00324 
00325         //!< expects coordinates in relation to THIS (current) element
00326         bool isIn(int x, int y, SDL_Rect *parentViewport);          //!< coordinates of screen 
00327         void reactOnMessageGrafikElement(CSMessage *message) {} 
00328         virtual void reactOnMessage(CSMessage *message) {reactOnMessageGrafikElement(message);} ///< to be overloaded
00329         virtual bool isTransparent(int x, int y, SDL_Rect *parentViewport) {return false;}          ///< to be overloaded (default false)
00330         virtual void putString(SDL_Surface *destination, SDL_Rect *parentViewport, int x1, int y1, const std::string &string);  ///< coordinates relativ to this element
00331         virtual void putString(SDL_Surface *destination, SDL_Rect *parentViewport, int x1, int y1, int color, const std::string &string);   ///< coordinates relativ to this element
00332         
00333         void line(SDL_Surface *destination, SDL_Rect *parentViewport, int x1, int y1, int x2, int y2, Uint32 color);        //!< coordinates relativ to this element
00334         void setActionId(int id) {mActionId=id;};
00335 
00336         virtual void lafChanged(int id);    //!< each element is registered to CSLAF, if LAF changes, this method is called (default does nothing!)
00337         bool isChild(CSGrafikElement *element);
00338         virtual void cursorDefault();
00339         virtual void cursorSizing();
00340         virtual CSMouseCursor *getCursor();
00341         void setCurrentLAFId(int id) {mCurrentLAFId = id;}
00342         int getCurrentLAFId(void) {return mCurrentLAFId;}
00343         virtual void setTooltipText(const std::string &s) {mTooltipText = s;}
00344         virtual std::string getTooltipText() {return mTooltipText;}
00345 
00346         virtual void layoutSetup(){}
00347         virtual bool getActive(){return mActive;}
00348         virtual void setActive(bool b){mActive = b;}
00349         virtual void setEnabled(bool b){mEnabled = b;}
00350         virtual bool getEnabled(){return mEnabled;}
00351         virtual void setActivated(bool b){mActivated = b;}
00352         virtual bool getActivated(){return mActivated;}
00353         virtual bool getModal() {return mModal;}
00354         virtual void setModal(bool m) {mModal = m;}
00355         virtual bool getVisible() {return mVisible;}
00356         virtual void setVisible(bool v); 
00357         virtual void setFocusable(bool b);
00358         virtual bool getFocusable() {return mFocusable;}
00359         bool getFocused() {return mFocused;}
00360         void setFocused(bool b) {mFocused = b;}     ///< only to be used from CSDesktop!
00361         virtual SDL_Rect getViewportArea() {return mViewportArea;}
00362 
00363         int getHeight() {if (mHeight<mMinHeight) return mMinHeight; return mHeight;}        ///< height of component
00364         int getWidth() {if (mWidth<mMinWidth) return mMinWidth; return mWidth;}         ///< width of component
00365         void setHeight(int h);                  ///< set height of component
00366         void setWidth(int w);                   ///< set width of component
00367         virtual CSFont *getFont(); //!<  returns the given gui font (see CSLAF)
00368         
00369         //! Font is not deleted here, since it is loaded by a LOADER::INSTANCE!
00370         //! (which keeps track of the instances!)
00371         virtual void setFont(CSFont *font) 
00372         {
00373             if (mFont != font)
00374             {
00375                 mFont = font;
00376                 layoutChanged();
00377             }
00378         }
00379 
00380         virtual void setInset(const CSInset &inset) {mInset = inset;}
00381         virtual CSInset getInset() {return mInset;}
00382         virtual void setBorder(CSBorder *border, bool deleteOldBorder = false);
00383         virtual CSBorder *getBorder();
00384 
00385         virtual void setArea(CSArea *area, bool deleteOldArea = false);
00386         virtual CSArea *getArea();
00387         
00388         int getBackgroundColor();
00389         void setBackgroundColor(int backgroundColor);
00390         int getTextColor();
00391         void setTextColor(int textColor);
00392         void setStyle(int style) {mStyle = style;}
00393         int getHorizontalElementSpacing();
00394         void setHorizontalElementSpacing(int horizontalElementSpacing);
00395         int getVerticalElementSpacing();
00396         void setVerticalElementSpacing(int verticalElementSpacing);
00397         void setBorderState(int state){mBorderState = state;}
00398 
00399         CSLayoutManager *getLayoutManager()
00400         {
00401             if (mMainElement == this)
00402             {
00403                 return getMainLayoutManager();
00404             }
00405             else
00406             {
00407                 return mMainElement->getLayoutManager();
00408             }
00409         }
00410         void setLayoutManager(CSLayoutManager *manager)
00411         {
00412             if (mMainElement == this)
00413             {
00414                 setMainLayoutManager(manager);
00415             }
00416             else
00417             {
00418                 mMainElement->setLayoutManager(manager);
00419             }
00420         }
00421         CSLayoutData getLayoutData() {return mLayoutData;} ///< pointer is faster, but more dangerous
00422         void setLayoutData(const CSLayoutData &layoutData) 
00423         {
00424             mLayoutData = layoutData;
00425             setPosition(mLayoutData.getX(), mLayoutData.getY());        ///< set X, Y coordinates in relation to parent (useaable Area)
00426             mLayoutManager->buildArea(this);
00427 
00428             
00429             layoutChanged();
00430         }
00431         //! each and every CSLayoutManager is freed by the CSGraphicElement, which
00432         //! receives it. Freed either in th edestructor, or by setting a new CSLayoutManager!
00433         void addMainElement(CSGrafikElement *element, int position);
00434         void addMainElement(CSGrafikElement *element, int x, int y);
00435         void addMainElement(CSGrafikElement *element);
00436         void addElement(CSGrafikElement *element, int position);
00437         void addElement(CSGrafikElement *element, int x, int y);
00438         void addFrontElement(CSGrafikElement *element, int x, int y); // koordinataes in Screen!
00439         void addFrontElementCenter(CSGrafikElement *element); // koordinataes in Screen!
00440         void addElement(CSGrafikElement *element);
00441 
00442         int getMinWidth() {if (getVisible()) return mMinWidth; return 0;}       //!< if not set defaults to 5 pixel
00443         void setMinWidth(int w) {mMinWidth = w;}
00444         int getMinHeight() {if (getVisible()) return mMinHeight; return 0;}     //!< if not set defaults to 5 pixel
00445         void setMinHeight(int h) {mMinHeight = h;}
00446         void removeFrontElement(CSGrafikElement *element);
00447         CSGrafikElement *removeElement(CSGrafikElement *element);
00448 
00449         void setViewportOffset(int x, int y)
00450         {
00451             mViewportOffsetX = x;
00452             mViewportOffsetY = y;
00453         }
00454 
00455         void getViewportOffset(int &x, int &y)
00456         {
00457             x = 0;
00458             y = 0;
00459             if (mParent)
00460             {
00461 //              mParent->getViewportOffset(x, y);
00462             }
00463             x += mViewportOffsetX;
00464             y += mViewportOffsetY;
00465         }
00466         void getViewportOffsetParent(int &x, int &y)
00467         {
00468             x = 0;
00469             y = 0;
00470             if (mParent)
00471             {
00472                 mParent->getViewportOffsetParent(x, y);
00473             }
00474             x += mViewportOffsetX;
00475             y += mViewportOffsetY;
00476         }
00477         
00478         void removeAllElements() 
00479         {
00480             if (mMainElement == this)
00481             {
00482                 removeMainAllElements();
00483             }
00484             else
00485             {
00486                 mMainElement->removeAllElements();
00487             }
00488         }       
00489         //! layoutChanged() changes only the "inside" of the current component
00490         //! children's layout changes etc.
00491         //! but the size or position of the current element ist not changed!
00492         void layoutChanged(bool sizing = false);
00493 };
00494 #endif // CSGRAFIK_ELEMENT_h
00495 
00496 
00497 
00498 

Generated on Wed Jul 14 00:43:29 2004 for CSLib by doxygen 1.3.6