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 #include "rect.h"
00010 #include "fontbase.h"
00011 #include "gadgetstyle.h"
00012 #include "gadgeteventhandlerlist.h"
00013 #include "woopsistring.h"
00014
00015 namespace WoopsiUI {
00016
00017 class GraphicsPort;
00018 class FontBase;
00019 class RectCache;
00020
00025 class Gadget {
00026 public:
00027
00031 enum CloseType {
00032 CLOSE_TYPE_CLOSE = 0,
00033 CLOSE_TYPE_HIDE = 1,
00034 CLOSE_TYPE_SHELVE = 2
00035 };
00036
00040 enum GadgetFlagType {
00041 GADGET_BORDERLESS = 0x0001,
00042 GADGET_DRAGGABLE = 0x0002,
00043 GADGET_PERMEABLE = 0x0004,
00044 GADGET_DOUBLE_CLICKABLE = 0x0008,
00045 GADGET_NO_RAISE_EVENTS = 0x0010,
00046 GADGET_DECORATION = 0x0020
00047 };
00048
00052 typedef struct {
00053 u8 clicked : 1;
00054 u8 hasFocus : 1;
00055 u8 dragging : 1;
00056 u8 deleted : 1;
00057 u8 shelved : 1;
00058 u8 borderless : 1;
00059 u8 draggable : 1;
00060 u8 drawingEnabled : 1;
00061 u8 enabled : 1;
00062 u8 decoration : 1;
00063 u8 permeable : 1;
00064 u8 erased : 1;
00065 u8 visibleRegionCacheInvalid : 1;
00066 u8 hidden : 1;
00067 u8 doubleClickable : 1;
00068 u8 modal : 1;
00069 u8 canReceiveFocus : 1;
00070 } Flags;
00071
00075 typedef struct {
00076 u32 value;
00077 WoopsiString name;
00078 } NameValuePair;
00079
00083 typedef struct {
00084 u8 top;
00085 u8 right;
00086 u8 bottom;
00087 u8 left;
00088 } GadgetBorderSize;
00089
00104 Gadget(s16 x, s16 y, u16 width, u16 height, u32 flags, GadgetStyle* style = NULL);
00105
00110 const s16 getX() const;
00111
00116 const s16 getY() const;
00117
00122 inline const u32 getRefcon() const { return _refcon; };
00123
00129 inline const CloseType getCloseType() { return _closeType; };
00130
00137 inline const bool hasFocus() const { return _flags.hasFocus; };
00138
00147 const bool isDeleted() const;
00148
00155 const bool isDrawingEnabled() const;
00156
00163 const bool isHidden() const;
00164
00171 const bool isEnabled() const;
00172
00179 inline const bool isDecoration() const { return _flags.decoration; };
00180
00187 inline const bool isPermeable() const { return _flags.permeable; };
00188
00193 inline const bool isDoubleClickable() const { return _flags.doubleClickable; };
00194
00199 inline const bool isBorderless() const { return _flags.borderless; };
00200
00205 inline const bool isClicked() const { return _flags.clicked; };
00206
00211 inline const bool isBeingDragged() const { return _flags.dragging; };
00212
00217 inline const bool isShelved() const { return _flags.shelved; };
00218
00223 const bool isModal() const;
00224
00229 const bool canReceiveFocus() const;
00230
00235 inline u16 getWidth() const { return _width; };
00236
00241 inline u16 getHeight() const { return _height; };
00242
00247 inline Gadget* getParent() const { return _parent; };
00248
00253 inline Gadget* getFocusedGadget() { return _focusedGadget; };
00254
00259 virtual const u8 getPhysicalScreenNumber() const;
00260
00265 inline const bool raisesEvents() const { return _gadgetEventHandlers->isEnabled(); };
00266
00273 virtual void getPreferredDimensions(Rect& rect) const;
00274
00281 void getClientRect(Rect& rect) const;
00282
00288 void getRectClippedToHierarchy(Rect& rect) const;
00289
00299 GraphicsPort* newGraphicsPort(bool isForeground);
00300
00313 GraphicsPort* newGraphicsPort(Rect clipRect);
00314
00320 WoopsiArray<Rect>* getForegroundRegions();
00321
00326 FontBase* getFont() const;
00327
00332 FontBase* getGlyphFont() const;
00333
00338 inline const u16 getBackColour() const { return _style.colours.back; };
00339
00344 inline const u16 getShineColour() const { return _style.colours.shine; };
00345
00350 inline const u16 getHighlightColour() const { return _style.colours.highlight; };
00351
00356 inline const u16 getShadowColour() const { return _style.colours.shadow; };
00357
00362 inline const u16 getFillColour() const { return _style.colours.fill; };
00363
00368 inline const u16 getDarkColour() const { return _style.colours.dark; };
00369
00375 u32 setRefcon(u32 refcon);
00376
00381 void setBorderless(bool isBorderless);
00382
00387 inline void setDraggable(const bool isDraggable) { _flags.draggable = isDraggable; };
00388
00393 inline void setPermeable(const bool isPermeable) { _flags.permeable = isPermeable; };
00394
00399 inline void setDoubleClickable(const bool isDoubleClickable) { _flags.doubleClickable = isDoubleClickable; };
00400
00406 inline void addGadgetEventHandler(GadgetEventHandler* eventHandler) { _gadgetEventHandlers->addGadgetEventHandler(eventHandler); };
00407
00412 inline void removeGadgetEventHandler(GadgetEventHandler* eventHandler) { _gadgetEventHandlers->removeGadgetEventHandler(eventHandler); };
00413
00418 inline void setRaisesEvents(const bool raisesEvents) {
00419 raisesEvents ? _gadgetEventHandlers->enable() : _gadgetEventHandlers->disable();
00420 };
00421
00426 inline void disableDrawing() { _flags.drawingEnabled = false; };
00427
00431 inline void enableDrawing() { _flags.drawingEnabled = true; };
00432
00437 inline void setBackColour(const u16 colour) { _style.colours.back = colour; };
00438
00443 inline void setShineColour(const u16 colour) { _style.colours.shine = colour; };
00444
00449 inline void setHighlightColour(const u16 colour) { _style.colours.highlight = colour; };
00450
00455 inline void setShadowColour(const u16 colour) { _style.colours.shadow = colour; };
00456
00461 inline void setFillColour(const u16 colour) { _style.colours.fill = colour; };
00462
00467 inline void setDarkColour(const u16 colour) { _style.colours.dark = colour; };
00468
00473 inline void setCloseType(const CloseType closeType) { _closeType = closeType; };
00474
00479 virtual void setFont(FontBase* font);
00480
00485 virtual void setGlyphFont(FontBase* font);
00486
00490 void redraw();
00491
00496 void erase();
00497
00502 bool enable();
00503
00508 bool disable();
00509
00515 void close();
00516
00524 bool shelve();
00525
00532 bool unshelve();
00533
00540 bool show();
00541
00548 bool hide();
00549
00559 bool click(s16 x, s16 y);
00560
00567 virtual bool isDoubleClick(s16 x, s16 y);
00568
00579 bool doubleClick(s16 x, s16 y);
00580
00591 bool shiftClick(s16 x, s16 y);
00592
00603 bool release(s16 x, s16 y);
00604
00613 bool drag(s16 x, s16 y, s16 vX, s16 vY);
00614
00620 bool keyPress(KeyCode keyCode);
00621
00627 bool keyRepeat(KeyCode keyCode);
00628
00634 bool keyRelease(KeyCode keyCode);
00635
00640 void lidClose();
00641
00646 void lidOpen();
00647
00652 bool focus();
00653
00658 bool blur();
00659
00667 bool moveTo(s16 x, s16 y);
00668
00675 bool resize(u16 width, u16 height);
00676
00687 bool changeDimensions(s16 x, s16 y, u16 width, u16 height);
00688
00693 bool raiseToTop();
00694
00699 bool lowerToBottom();
00700
00707 bool raiseGadgetToTop(Gadget* gadget);
00708
00715 bool lowerGadgetToBottom(Gadget* gadget);
00716
00722 void moveChildToDeleteQueue(Gadget* gadget);
00723
00732 bool moveChildToShelvedList(Gadget* gadget);
00733
00743 bool moveShelvedToChildList(Gadget* gadget);
00744
00751 void setFocusedGadget(Gadget* gadget);
00752
00759 bool checkCollision(s16 x, s16 y) const;
00760
00769 bool checkCollision(s16 x, s16 y, u16 width, u16 height) const;
00770
00776 bool checkCollision(Gadget* gadget) const;
00777
00784 void invalidateLowerGadgetsVisibleRectCache(Gadget* gadget);
00785
00793 void addGadget(Gadget* gadget);
00794
00802 void insertGadget(Gadget* gadget);
00803
00809 inline void setParent(Gadget* parent) { _parent = parent; };
00810
00814 void cacheVisibleRects() const;
00815
00820 void invalidateVisibleRectCache();
00821
00826 void eraseGadget(Gadget* gadget);
00827
00833 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 WoopsiString& name, u32 value);
00885
00891 void showContextMenu(s16 x, s16 y);
00892
00897 virtual bool handleContextMenuSelection(const ListDataItem* 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
00946 void setBorderSize(const GadgetBorderSize& borderSize);
00947
00948 protected:
00949 s16 _x;
00950 s16 _y;
00951 u16 _width;
00952 u16 _height;
00953 u32 _refcon;
00955
00956 s16 _grabPointX;
00957 s16 _grabPointY;
00958 s16 _newX;
00959 s16 _newY;
00961
00962 GadgetStyle _style;
00964
00965 Flags _flags;
00967
00968 GadgetEventHandlerList* _gadgetEventHandlers;
00970
00971 u32 _lastClickTime;
00972 s16 _lastClickX;
00973 s16 _lastClickY;
00974 s16 _doubleClickBounds;
00976
00977 Gadget* _parent;
00978 Gadget* _focusedGadget;
00979 WoopsiArray<Gadget*> _gadgets;
00980 WoopsiArray<Gadget*> _shelvedGadgets;
00982
00983 u8 _decorationCount;
00985
00986 RectCache* _rectCache;
00988 CloseType _closeType;
00990 GadgetBorderSize _borderSize;
00992
00993 WoopsiArray<NameValuePair> _contextMenuItems;
00998 virtual ~Gadget();
00999
01006 virtual inline void drawContents(GraphicsPort* port) { };
01007
01014 virtual void drawBorder(GraphicsPort* port) { };
01015
01024 bool checkCollisionWithForegroundRects(s16 x, s16 y) const;
01025
01040 const s16 calculatePhysicalScreenY(s16 y) const;
01041
01051 const u8 calculatePhysicalScreenNumber(s16 y) const;
01052
01056 void drawChildren();
01057
01064 void closeChild(Gadget* gadget);
01065
01072 void shelveChild(Gadget* gadget);
01073
01080 void redrawDirtyChildren(WoopsiArray<Rect>* invalidRects, Gadget* sender);
01081
01089 GraphicsPort* newInternalGraphicsPort(Rect clipRect);
01090
01096 const s32 getHigherVisibleGadget(const s32 startIndex) const;
01097
01103 const s32 getLowerVisibleGadget(const s32 startIndex) const;
01104
01110 void startDragging(s16 x, s16 y);
01111
01115 void stopDragging(s16 x, s16 y);
01116
01120 inline Gadget(const Gadget& gadget) { };
01121
01129 virtual inline void onClick(s16 x, s16 y) { };
01130
01140 virtual inline void onDoubleClick(s16 x, s16 y) { };
01141
01149 virtual inline void onShiftClick(s16 x, s16 y) { };
01150
01158 virtual inline void onRelease(s16 x, s16 y) { };
01159
01167 virtual inline void onReleaseOutside(s16 x, s16 y) { };
01168
01178 virtual inline void onDrag(s16 x, s16 y, s16 vX, s16 vY) { };
01179
01185 virtual inline void onDragStart() { };
01186
01192 virtual inline void onDragStop() { };
01193
01200 virtual inline void onKeyPress(KeyCode keyCode) { };
01201
01208 virtual inline void onKeyRelease(KeyCode keyCode) { };
01209
01216 virtual inline void onKeyRepeat(KeyCode keyCode) { };
01217
01223 virtual inline void onFocus() { };
01224
01230 virtual inline void onBlur() { };
01231
01237 virtual inline void onLidOpen() { };
01238
01244 virtual inline void onLidClose() { };
01245
01251 virtual inline void onEnable() { };
01252
01258 virtual inline void onDisable() { };
01259
01267 virtual inline void onResize(u16 width, u16 height) { };
01268 };
01269 }
01270
01271 #endif