00001 #ifndef _GADGET_H_
00002 #define _GADGET_H_
00003
00004 #include <nds.h>
00005 #include "defines.h"
00006 #include "gadgeteventhandler.h"
00007 #include "woopsiarray.h"
00008 #include "glyphs.h"
00009
00010 namespace WoopsiUI {
00011
00012 class GraphicsPort;
00013 class FontBase;
00014 class RectCache;
00015
00020 class Gadget {
00021 public:
00022
00026 enum OutlineType {
00027 OUTLINE_CLICK_DEPENDENT = 0,
00028 OUTLINE_OUT = 1,
00029 OUTLINE_IN = 2,
00030 OUTLINE_OUT_IN = 3
00031 };
00032
00036 enum CloseType {
00037 CLOSE_TYPE_CLOSE = 0,
00038 CLOSE_TYPE_HIDE = 1,
00039 CLOSE_TYPE_SHELVE = 2
00040 };
00041
00045 enum GadgetFlagType {
00046 GADGET_BORDERLESS = 0x0001,
00047 GADGET_DRAGGABLE = 0x0002,
00048 GADGET_PERMEABLE = 0x0004,
00049 GADGET_DOUBLE_CLICKABLE = 0x0008,
00050 GADGET_NO_SHIFT_CLICK_CHILDREN = 0x0010,
00051 GADGET_NO_RAISE_EVENTS = 0x0020,
00052 GADGET_DECORATION = 0x0040
00053 };
00054
00058 typedef struct {
00059 s16 x;
00060 s16 y;
00061 s32 width;
00062 s32 height;
00063 } Rect;
00064
00068 typedef struct {
00069 u8 clicked : 1;
00070 u8 hasFocus : 1;
00071 u8 dragging : 1;
00072 u8 deleted : 1;
00073 u8 shelved : 1;
00074 u8 borderless : 1;
00075 u8 draggable : 1;
00076 u8 drawingEnabled : 1;
00077 u8 enabled : 1;
00078 u8 decoration : 1;
00079 u8 permeable : 1;
00080 u8 raisesEvents : 1;
00081 u8 erased : 1;
00082 u8 shiftClickChildren : 1;
00083 u8 visibleRegionCacheInvalid : 1;
00084 u8 hidden : 1;
00085 u8 doubleClickable : 1;
00086 u8 modal : 1;
00087 } Flags;
00088
00092 typedef struct {
00093 u32 value;
00094 char* name;
00095 } NameValuePair;
00096
00108 Gadget(s16 x, s16 y, u16 width, u16 height, u32 flags, FontBase* font = NULL);
00109
00114 const s16 getX() const;
00115
00120 const s16 getY() const;
00121
00126 inline const u32 getRefcon() const { return _refcon; };
00127
00133 inline const CloseType getCloseType() { return _closeType; };
00134
00141 inline const bool hasFocus() const { return _flags.hasFocus; };
00142
00151 const bool isDeleted() const;
00152
00159 const bool isDrawingEnabled() const;
00160
00167 const bool isHidden() const;
00168
00175 const bool isEnabled() const;
00176
00183 inline const bool isDecoration() const { return _flags.decoration; };
00184
00191 inline const bool isPermeable() const { return _flags.permeable; };
00192
00197 inline const bool isDoubleClickable() const { return _flags.doubleClickable; };
00198
00203 inline const bool isBorderless() const { return _flags.borderless; };
00204
00209 inline const bool isClicked() const { return _flags.clicked; };
00210
00215 inline const bool isShelved() const { return _flags.shelved; };
00216
00221 const bool isModal() const;
00222
00227 inline const bool getShiftClickChildren() const { return _flags.shiftClickChildren; };
00228
00233 inline void setShiftClickChildren(const u32 shiftClickChildren) { _flags.shiftClickChildren = shiftClickChildren; };
00234
00239 inline u16 getWidth() const { return _width; };
00240
00245 inline u16 getHeight() const { return _height; };
00246
00251 inline Gadget* getParent() const { return _parent; };
00252
00257 inline Gadget* getFocusedGadget() { return _focusedGadget; };
00258
00263 inline const u8 getPhysicalScreenNumber() const { return calculatePhysicalScreenNumber(getY()); };
00264
00269 inline const bool raisesEvents() const { return _flags.raisesEvents & !isDeleted(); };
00270
00277 virtual void getPreferredDimensions(Rect& rect) const;
00278
00285 virtual void getClientRect(Rect& rect) const;
00286
00292 void getRectClippedToHierarchy(Rect& rect) const;
00293
00303 virtual GraphicsPort* newGraphicsPort(bool isForeground);
00304
00317 virtual GraphicsPort* newGraphicsPort(Rect clipRect);
00318
00324 WoopsiArray<Rect>* getForegroundRegions();
00325
00331 WoopsiArray<Rect>* getBackgroundRegions();
00332
00337 FontBase* getFont() const;
00338
00343 inline const u16 getBackColour() const { return _backColour; };
00344
00349 inline const u16 getShineColour() const { return _shineColour; };
00350
00355 inline const u16 getHighlightColour() const { return _highlightColour; };
00356
00361 inline const u16 getShadowColour() const { return _shadowColour; };
00362
00367 inline const u16 getFillColour() const { return _fillColour; };
00368
00373 inline const u16 getDarkColour() const { return _darkColour; };
00374
00379 inline const OutlineType getOutlineType() const { return _outline; };
00380
00386 u32 setRefcon(u32 refcon);
00387
00392 void setBorderless(bool isBorderless);
00393
00398 inline void setDraggable(const bool isDraggable) { _flags.draggable = isDraggable; };
00399
00404 inline void setPermeable(const bool isPermeable) { _flags.permeable = isPermeable; };
00405
00410 inline void setDoubleClickable(const bool isDoubleClickable) { _flags.doubleClickable = isDoubleClickable; };
00411
00416 inline void setOutlineType(const OutlineType outline) { _outline = outline; };
00417
00423 inline void addGadgetEventHandler(GadgetEventHandler* eventHandler) { _gadgetEventHandlers.push_back(eventHandler); };
00424
00429 void removeGadgetEventHandler(GadgetEventHandler* eventHandler);
00430
00435 inline void setRaisesEvents(const bool raisesEvents) { _flags.raisesEvents = raisesEvents; };
00436
00441 inline void disableDrawing() { _flags.drawingEnabled = false; };
00442
00446 inline void enableDrawing() { _flags.drawingEnabled = true; };
00447
00452 inline void setBackColour(const u16 colour) { _backColour = colour; };
00453
00458 inline void setShineColour(const u16 colour) { _shineColour = colour; };
00459
00464 inline void setHighlightColour(const u16 colour) { _highlightColour = colour; };
00465
00470 inline void setShadowColour(const u16 colour) { _shadowColour = colour; };
00471
00476 inline void setFillColour(const u16 colour) { _fillColour = colour; };
00477
00482 inline void setDarkColour(const u16 colour) { _darkColour = colour; };
00483
00488 inline void setCloseType(const CloseType closeType) { _closeType = closeType; };
00489
00494 virtual void setFont(FontBase* font);
00495
00499 virtual void redraw();
00500
00505 virtual void erase();
00506
00511 virtual bool enable();
00512
00517 virtual bool disable();
00518
00524 virtual void close();
00525
00533 virtual bool shelve();
00534
00541 virtual bool unshelve();
00542
00549 virtual bool show();
00550
00557 virtual bool hide();
00558
00565 virtual bool click(s16 x, s16 y);
00566
00573 virtual bool doubleClick(s16 x, s16 y);
00574
00581 virtual bool shiftClick(s16 x, s16 y);
00582
00589 virtual bool release(s16 x, s16 y);
00590
00599 virtual bool drag(s16 x, s16 y, s16 vX, s16 vY);
00600
00606 virtual bool keyPress(KeyCode keyCode);
00607
00613 virtual bool keyRelease(KeyCode keyCode);
00614
00619 virtual void lidClose();
00620
00625 virtual void lidOpen();
00626
00631 virtual bool focus();
00632
00637 virtual bool blur();
00638
00646 virtual bool moveTo(s16 x, s16 y);
00647
00654 virtual bool resize(u16 width, u16 height);
00655
00666 virtual bool changeDimensions(s16 x, s16 y, u16 width, u16 height);
00667
00672 virtual bool raiseToTop();
00673
00678 virtual bool lowerToBottom();
00679
00686 virtual bool raiseGadgetToTop(Gadget* gadget);
00687
00694 virtual bool lowerGadgetToBottom(Gadget* gadget);
00695
00701 void moveChildToDeleteQueue(Gadget* gadget);
00702
00711 bool moveChildToShelvedList(Gadget* gadget);
00712
00722 bool moveShelvedToChildList(Gadget* gadget);
00723
00730 virtual void setFocusedGadget(Gadget* gadget);
00731
00738 bool checkCollision(s16 x, s16 y) const;
00739
00748 bool checkCollision(s16 x, s16 y, u16 width, u16 height) const;
00749
00755 bool checkCollision(Gadget* gadget) const;
00756
00763 void invalidateLowerGadgetsVisibleRectCache(Gadget* gadget);
00764
00769 void unregisterChildrenFromVBL();
00770
00778 void addGadget(Gadget* gadget);
00779
00787 void insertGadget(Gadget* gadget);
00788
00794 inline void setParent(Gadget* parent) { _parent = parent; };
00795
00801 virtual void setDragging(u16 x, u16 y);
00802
00806 void cacheVisibleRects();
00807
00812 void invalidateVisibleRectCache();
00813
00820 virtual inline void draw(Rect clipRect) { };
00821
00826 virtual void eraseGadget(Gadget* gadget);
00827
00833 virtual void redrawDirty(WoopsiArray<Rect>* invalidRects, Gadget* sender);
00834
00839 void clipRectToHierarchy(Rect& rect) const;
00840
00846 virtual bool swapGadgetDepth(Gadget* gadget);
00847
00852 bool swapDepth();
00853
00858 inline void destroy() { delete this; };
00859
00867 bool remove();
00868
00877 bool removeChild(Gadget* gadget);
00878
00884 void addContextMenuItem(const char* name, u32 value);
00885
00891 virtual void showContextMenu(s16 x, s16 y);
00892
00897 virtual bool handleContextMenuSelection(const ContextMenuItem* item);
00898
00902 void goModal();
00903
00907 inline void stopModal() { _flags.modal = false; };
00908
00914 const s32 getGadgetIndex(const Gadget* gadget) const;
00915
00921 const Gadget* getChild(u32 index) const;
00922
00927 const s32 getChildCount() const { return _gadgets.size(); };
00928
00933 const inline s32 getDecorationCount() const { return _decorationCount; };
00934
00939 inline RectCache* getRectCache() const { return _rectCache; };
00940
00941 protected:
00942 s16 _x;
00943 s16 _y;
00944 u16 _width;
00945 u16 _height;
00946 u32 _refcon;
00948
00949 s16 _grabPointX;
00950 s16 _grabPointY;
00951 s16 _newX;
00952 s16 _newY;
00954
00955 u16 _backColour;
00956 u16 _shineColour;
00957 u16 _highlightColour;
00958 u16 _shadowColour;
00959 u16 _fillColour;
00960 u16 _darkColour;
00962
00963 Flags _flags;
00965
00966 WoopsiArray<GadgetEventHandler*> _gadgetEventHandlers;
00968
00969 u32 _lastClickTime;
00970 s16 _lastClickX;
00971 s16 _lastClickY;
00972 s16 _doubleClickBounds;
00973 s16 _doubleClickTime;
00975
00976 Gadget* _parent;
00977 Gadget* _focusedGadget;
00978 WoopsiArray<Gadget*> _gadgets;
00979 WoopsiArray<Gadget*> _shelvedGadgets;
00981
00982 u8 _decorationCount;
00984
00985 RectCache* _rectCache;
00987 OutlineType _outline;
00988 CloseType _closeType;
00990 FontBase* _font;
00992
00993 WoopsiArray<NameValuePair> _contextMenuItems;
00998 virtual ~Gadget();
00999
01014 const s16 calculatePhysicalScreenY(s16 y) const;
01015
01025 const u8 calculatePhysicalScreenNumber(s16 y) const;
01026
01031 void clear(Rect clipRect);
01032
01037 void clear();
01038
01042 void drawChildren();
01043
01050 virtual void closeChild(Gadget* gadget);
01051
01058 virtual void shelveChild(Gadget* gadget);
01059
01066 virtual void redrawDirtyChildren(WoopsiArray<Rect>* invalidRects, Gadget* sender);
01067
01079 virtual GraphicsPort* newInternalGraphicsPort(bool isForeground);
01080
01088 virtual GraphicsPort* newInternalGraphicsPort(Rect clipRect);
01089
01095 void raiseClickEvent(s16 x, s16 y);
01096
01102 void raiseDoubleClickEvent(s16 x, s16 y);
01103
01109 void raiseShiftClickEvent(s16 x, s16 y);
01110
01116 void raiseReleaseEvent(s16 x, s16 y);
01117
01123 void raiseReleaseOutsideEvent(s16 x, s16 y);
01124
01132 void raiseDragEvent(s16 x, s16 y, s16 vX, s16 vY);
01133
01137 void raiseMoveForwardEvent();
01138
01142 void raiseMoveBackwardEvent();
01143
01148 void raiseKeyPressEvent(KeyCode keyCode);
01149
01154 void raiseKeyReleaseEvent(KeyCode keyCode);
01155
01159 void raiseLidCloseEvent();
01160
01164 void raiseLidOpenEvent();
01165
01169 void raiseFocusEvent();
01170
01174 void raiseBlurEvent();
01175
01179 void raiseCloseEvent();
01180
01184 void raiseHideEvent();
01185
01189 void raiseShowEvent();
01190
01194 void raiseShelveEvent();
01195
01199 void raiseUnshelveEvent();
01200
01204 void raiseEnableEvent();
01205
01209 void raiseDisableEvent();
01210
01214 void raiseValueChangeEvent();
01215
01221 void raiseResizeEvent(u16 width, u16 height);
01222
01230 void raiseMoveEvent(s16 x, s16 y, s16 vX, s16 vY);
01231
01236 void raiseContextMenuSelectionEvent(const ContextMenuItem* contextMenuItem);
01237
01253 void raiseActionEvent(s16 x, s16 y, s16 vX, s16 vY, KeyCode keyCode);
01254
01260 const s32 getHigherVisibleGadget(const s32 startIndex) const;
01261
01267 const s32 getLowerVisibleGadget(const s32 startIndex) const;
01268
01272 inline Gadget(const Gadget& gadget) { };
01273 };
01274 }
01275
01276 #endif