DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator
src/libs/gui_tk/gui_tk.h
Go to the documentation of this file.
00001 
00106 #ifndef GUI__TOOLKIT_H
00107 #define GUI__TOOLKIT_H
00108 
00109 #define imin(x,y) ((x)<(y)?(x):(y))
00110 #define imax(x,y) ((x)>(y)?(x):(y))
00111 #define isign(x) (((x)<0?-1:1))
00112 
00119 #ifdef _MSC_VER
00120 typedef signed __int8   int8_t;
00121 typedef signed __int16  int16_t;
00122 typedef signed __int32  int32_t;
00123 typedef unsigned __int8  uint8_t;
00124 typedef unsigned __int16 uint16_t;
00125 typedef unsigned __int32 uint32_t;
00126 #else
00127 #include <stdint.h>
00128 #endif
00129 
00130 #include <list>
00131 #include <map>
00132 #include <vector>
00133 #include <typeinfo>
00134 #include <string>
00135 #include <iostream>
00136 
00138 namespace GUI {
00139 
00141 typedef uint32_t RGB;
00142 
00144 namespace Color {
00146 const RGB Transparent = 0x00ffffff;
00147 
00149 const RGB Black = 0xff000000;
00150 
00152 const RGB White = 0xffffffff;
00153 
00155 const RGB AlphaMask = 0xff000000;
00156 
00158 const int AlphaShift = 24;
00159 
00161 const RGB RedMask = 0x00ff0000;
00162 
00164 const RGB Red = Black|RedMask;
00165 
00167 const int RedShift = 16;
00168 
00170 const RGB GreenMask = 0x0000ff00;
00171 
00173 const RGB Green = Black|GreenMask;
00174 
00176 const int GreenShift = 8;
00177 
00179 const RGB BlueMask = 0x000000ff;
00180 
00182 const RGB Blue = Black|BlueMask;
00183 
00185 const int BlueShift = 0;
00186 
00188 const RGB Magenta = Red|Blue;
00189 
00191 const RGB MagentaMask = RedMask|BlueMask;
00192 
00194 const RGB Cyan = Green|Blue;
00195 
00197 const RGB CyanMask = GreenMask|BlueMask;
00198 
00200 const RGB Yellow = Red|Green;
00201 
00203 const RGB YellowMask = RedMask|GreenMask;
00204 
00206 const RGB Grey50 = 0xff808080;
00207 
00209 extern RGB Background3D;
00210 
00212 extern RGB Light3D;
00213 
00215 extern RGB Shadow3D;
00216 
00218 extern RGB Border;
00219 
00221 extern RGB Text;
00222 
00224 extern RGB Background;
00225 
00227 extern RGB SelectionBackground;
00228 
00230 extern RGB SelectionForeground;
00231 
00233 extern RGB EditableBackground;
00234 
00236 extern RGB Titlebar;
00237 
00239 extern RGB TitlebarText;
00240 
00242 static inline RGB rgba(unsigned int r, unsigned int g, unsigned int b, unsigned int a=0) {
00243         return (((r&255)<<RedShift)|((g&255)<<GreenShift)|((b&255)<<BlueShift)|((a&255)<<AlphaShift));
00244 }
00245 
00247 static inline unsigned int R(RGB val) { return ((val&Color::RedMask)>>Color::RedShift); }
00249 static inline unsigned int G(RGB val) { return ((val&Color::GreenMask)>>Color::GreenShift); }
00251 static inline unsigned int B(RGB val) { return ((val&Color::BlueMask)>>Color::BlueShift); }
00253 static inline unsigned int A(RGB val) { return ((val&Color::AlphaMask)>>Color::AlphaShift); }
00254 
00255 }
00256 
00258 enum MouseButton { NoButton, Left, Right, Middle, WheelUp, WheelDown, WheelLeft, WheelRight };
00259 
00261 typedef unsigned int Size;
00262 
00264 typedef uint32_t Char;
00265 
00267 typedef unsigned int Ticks;
00268 
00270 class Key {
00271 public:
00273 
00275         Char character;
00277 
00280         enum Special {
00281                 None,
00282                 F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12,
00283                 Up, Down, Left, Right, Backspace, Tab, Backtab, Enter, Escape,
00284                 Home, End, PageUp, PageDown, Insert, Delete, Menu,
00285                 Print, Pause, Break, CapsLock, NumLock, ScrollLock,
00286                 Alt, Ctrl, Shift, Windows
00287         } special;
00289         bool shift;
00291         bool ctrl;
00293         bool alt;
00295 
00296         bool windows;
00297 
00299         Key(GUI::Char character, Special special, bool shift, bool ctrl, bool alt, bool windows) :
00300                 character(character), special(special),
00301                 shift(shift), ctrl(ctrl), alt(alt), windows(windows) {}
00302 };
00303 
00304 class Drawable;
00305 class String;
00306 
00324 template <typename STR> class NativeString {
00325 protected:
00326         friend class String;
00327 
00329         static void getString(String &dest, const STR &src)  { (void)dest; (void)src; STR::_this_string_type_is_not_supported_(); }
00330 
00336         static STR& getNative(const String &src) { (void)src; STR::_this_string_type_is_not_supported_();return*new STR(); }
00337 };
00338 
00339 template <typename STR> class NativeString<STR*> {
00340 protected:
00341         friend class String;
00342         static void getString(String &dest, const STR *src);
00343         static STR* getNative(const String &src);
00344 };
00345 
00346 template <typename STR, Size N> class NativeString<STR[N]> : public NativeString<STR*> {};
00347 template <typename STR, Size N> class NativeString<const STR[N]> : public NativeString<STR*> {};
00348 template <typename STR> class NativeString<const STR*> : public NativeString<STR*> {};
00349 
00351 struct ltvoid { bool operator()(const void* s1, const void* s2) const { return s1 < s2; } };
00352 
00363 class String : public std::vector<Char> {
00364 protected:
00365         template <typename STR> friend class NativeString;
00367         class Native { public: virtual ~Native() {}; };
00369         template <typename STR> class NativeArray: public Native {
00370                 STR *data;
00371         public:
00372                 NativeArray(STR *data) : data(data) {}
00373                 virtual ~NativeArray() { delete[] data; }
00374         };
00375         template <typename STR> class NativeObject: public Native {
00376                 STR *data;
00377         public:
00378                 NativeObject(STR *data) : data(data) {}
00379                 virtual ~NativeObject() { delete data; }
00380         };
00381 
00382 private:
00384         mutable std::map<const class std::type_info *, Native *, ltvoid> strings;
00385 
00386 protected:
00388         void addNative(Native *dest) const {
00389                 const class std::type_info &type = typeid(dest);
00390                 if (strings[&type] != NULL) delete strings[&type];
00391                 strings[&type] = dest;
00392         }
00393 
00394 public:
00396         template <typename STR> String(const STR& src) { NativeString<STR>::getString(*this, src); }
00397 
00399         template <class InputIterator> String(InputIterator a, InputIterator b) : std::vector<Char>(a,b) {}
00400 
00402         String(const String &src) : std::vector<Char>(src), strings() {};
00403 
00405         String() { }
00406 
00408         ~String() {
00409                 for (std::map<const class std::type_info *, Native *, ltvoid>::iterator i = strings.begin(); i != strings.end(); ++i)
00410                         delete (*i).second;
00411         };
00412 
00414 
00416         template <typename T> operator T() const { return NativeString<T>::getNative(*this); }
00417 
00419         template <typename T> bool operator==(const T &src) const { return *this == String(src); }
00421         bool operator==(const String &src) const { return *(std::vector<Char>*)this == src; }
00422 
00424         template <typename T> bool operator!=(const T &src) const { return *this != String(src); }
00426         bool operator!=(const String &src) const { return *(std::vector<Char>*)this != src; }
00427 };
00428 
00429 template <typename STR> void NativeString<STR*>::getString(String &dest, const STR* src) {
00430         Size strlen = 0;
00431         while (src[strlen]) strlen++;
00432         dest.resize(strlen);
00433         for (strlen = 0; src[(unsigned int)strlen]; strlen++) dest[(unsigned int)strlen] = (unsigned int)(sizeof(STR)==1?(unsigned char)src[strlen]:sizeof(STR)==2?(unsigned short)src[strlen]:src[strlen]);
00434 }
00435 
00436 template <typename STR> STR* NativeString<STR*>::getNative(const String &src) {
00437         Size strlen = (Size)src.size();
00438         STR* dest = new STR[strlen+1];
00439         dest[strlen] = 0;
00440         for (; strlen > 0; strlen--) dest[strlen-1] = src[strlen-1];
00441         src.addNative(new String::NativeArray<const STR>(dest));
00442         return dest;
00443 }
00444 
00445 template <> class NativeString<std::string*> {
00446 protected:
00447         friend class String;
00448         static void getString(String &dest, const std::string *src) {
00449                 Size strlen = (Size)src->length();
00450                 dest.resize(strlen);
00451                 for (Size i = 0; i< strlen; i++) dest[i] = (unsigned int)((*src)[i]);
00452         }
00453         static std::string* getNative(const String &src) {
00454                 Size strlen = (Size)src.size();
00455                 std::string* dest = new std::string();
00456                 for (Size i = 0; i < strlen; i++) dest->append(1,src[i]);
00457                 src.addNative(new String::NativeObject<std::string>(dest));
00458                 return dest;
00459         }
00460 };
00461 
00462 template <> class NativeString<const std::string*> : public NativeString<std::string*> {};
00463 
00464 template <> class NativeString<std::string> {
00465 protected:
00466         friend class String;
00467         static void getString(String &dest, const std::string &src) {
00468                 Size strlen = (Size)src.length();
00469                 dest.resize(strlen);
00470                 for (Size i = 0; i< strlen; i++) dest[i] = (unsigned int)src[i];
00471         }
00472         static std::string& getNative(const String &src) {
00473                 Size strlen = (Size)src.size();
00474                 std::string* dest = new std::string();
00475                 for (Size i = 0; i < strlen; i++) dest->append(1,src[i]);
00476                 src.addNative(new String::NativeObject<std::string>(dest));
00477                 return *dest;
00478         }
00479 };
00480 
00481 template <> class NativeString<const std::string> : public NativeString<std::string> {};
00482 
00483 class ToplevelWindow;
00484 class Menu;
00485 class TransientWindow;
00486 class Screen;
00487 class Window;
00488 
00490 struct Window_Callback {
00491 public:
00493                 virtual void windowMoved(Window *win, int x, int y) = 0;
00494                 virtual ~Window_Callback() {}
00495 };
00496 
00497 
00507 class Window {
00508 protected:
00509         friend class ToplevelWindow;
00510         friend class TransientWindow;
00511         friend class Menu;
00512 
00514         int width;
00516         int height;
00518         int x;
00520         int y;
00521 
00523         bool dirty;
00524 
00526         bool visible;
00527 
00529         Window *const parent;
00530 
00532 
00533         Window  *mouseChild;
00534 
00536 
00538         std::list<Window *> children;
00539 
00541         std::list<Window_Callback *> movehandlers;
00542 
00544         virtual void addChild(Window *child);
00545 
00547         virtual void removeChild(Window *child);
00548 
00550         void setDirty() { if (dirty) return; dirty = true; if (parent != NULL) parent->setDirty(); };
00551 
00553         virtual void setClipboard(const String &s) { parent->setClipboard(s); };
00554 
00556         virtual const String& getClipboard() { return parent->getClipboard(); };
00557 
00559         Window();
00560 
00562         virtual void focusChanged(bool gained) {
00563                 if (children.size() > 0) children.back()->focusChanged(gained);
00564         }
00565 
00566 public:
00567 
00569         void addWindowHandler(Window_Callback *handler) { movehandlers.push_back(handler); }
00570 
00572         void removeWindowHandler(Window_Callback *handler) { movehandlers.remove(handler); }
00573 
00575         Window(Window *parent, int x, int y, int w, int h);
00576 
00578         virtual ~Window();
00579 
00581 
00583         virtual void resize(int w, int h);
00585         virtual int getWidth() const { return width; }
00587         virtual int getHeight() const { return height; }
00588 
00590 
00592         virtual void move(int x, int y);
00594         virtual int getX() const { return x; }
00596         virtual int getY() const { return y; }
00598         virtual int getScreenX() const { return (parent == NULL?0:parent->getScreenX()+x); }
00600         virtual int getScreenY() const { return (parent == NULL?0:parent->getScreenY()+y); }
00601 
00603         virtual void paintAll(Drawable &d) const;
00604 
00606         virtual void paint(Drawable &d) const { (void)d; };
00607 
00609 
00610         virtual void setVisible(bool v) { visible = !!v; parent->setDirty(); }
00611 
00613         virtual bool isVisible() const { return (!parent || parent->isVisible()) && visible; }
00614 
00616 
00617         Window *getParent() const { return parent; }
00618 
00620         Screen *getScreen();
00621 
00623         virtual bool hasFocus() const { return parent->hasFocus() && *parent->children.rbegin() == this; }
00624 
00626         virtual bool mouseMoved(int x, int y);
00628         virtual bool mouseDragged(int x, int y, MouseButton button);
00630         virtual bool mouseDown(int x, int y, MouseButton button);
00632         virtual bool mouseUp(int x, int y, MouseButton button);
00634 
00635         virtual bool mouseClicked(int x, int y, MouseButton button);
00637         virtual bool mouseDoubleClicked(int x, int y, MouseButton button);
00638 
00640         virtual bool keyDown(const Key &key);
00642         virtual bool keyUp(const Key &key);
00643 
00645 
00646         virtual bool raise() {
00647                 Window *last = parent->children.back();
00648                 for (Window *cur = parent->children.back(); cur != this; cur = parent->children.back()) {
00649                         parent->children.remove(cur);
00650                         parent->children.push_front(cur);
00651                 }
00652                 if (last != this) {
00653                         focusChanged(true);
00654                         last->focusChanged(false);
00655                 }
00656                 parent->setDirty();
00657                 return true;
00658         }
00659 
00661         virtual void lower() {
00662                 parent->children.remove(this);
00663                 parent->children.push_front(this);
00664                 if (this != parent->children.back()) {
00665                         parent->children.back()->focusChanged(true);
00666                         focusChanged(false);
00667                 }
00668                 parent->setDirty();
00669         }
00670 
00672         Window *getChild(int n) {
00673                 for (std::list<Window *>::const_iterator i = children.begin(); i != children.end(); ++i) {
00674                         if (n--) return *i;
00675                 }
00676                 return NULL;
00677         }
00678 
00679 };
00680 
00694 class Screen : public Window {
00695 protected:
00697         Drawable *const buffer;
00698 
00700         String clipboard;
00701 
00703         MouseButton button;
00704 
00706         virtual void rgbToSurface(RGB color, void **pixel) = 0;
00707 
00709         virtual RGB surfaceToRGB(void *pixel) = 0;
00710 
00712         Screen(Size width, Size height);
00713 
00715         Screen(Drawable *d);
00716 
00717 public:
00719         virtual ~Screen();
00720 
00722         template <typename STR> void setClipboard(const STR s) { this->setClipboard(String(s)); }
00723 
00725         virtual void setClipboard(const String &s) { clipboard = s; }
00726 
00728         virtual const String& getClipboard() { return clipboard; }
00729 
00731         virtual void resize(int w, int h);
00732 
00734         virtual void move(int x, int y);
00735 
00737         virtual bool hasFocus() const { return true; }
00738 
00740 
00744         Ticks update(void *surface, Ticks ticks = 1);
00745 
00747         virtual void paint(Drawable &d) const;
00748 };
00749 
00750 class Timer;
00751 
00753 struct Timer_Callback {
00754 public:
00756 
00761                 virtual Ticks timerExpired(Ticks time) = 0;
00762                 virtual ~Timer_Callback() {}
00763 };
00764 
00774 class Timer {
00775 protected:
00777         static Ticks ticks;
00778 
00780         struct ltuint { bool operator()(Ticks i1, Ticks i2) const {
00781                 return (i1 < i2);
00782         } };
00783 
00785         static std::multimap<Ticks,Timer_Callback*,ltuint> timers;
00786 
00787 public:
00789         static void check(Ticks ticks);
00790         static void check_to(Ticks ticks);
00791 
00793 
00794         static void add(Timer_Callback *cb, const Ticks ticks) { timers.insert(std::pair<const Ticks,Timer_Callback *>(ticks+Timer::ticks,cb)); }
00795 
00796         static void remove(const Timer_Callback *const cb);
00797 
00799         static Ticks now() { return ticks; }
00800 
00802         static Ticks next();
00803 };
00804 
00805 
00811 class ScreenRGB32le : public Screen {
00812 protected:
00814         virtual void rgbToSurface(RGB color, void **pixel) { RGB **p = (RGB **)pixel; **p = color; (*p)++; };
00815 
00817         virtual RGB surfaceToRGB(void *pixel) { return *(RGB*)pixel; };
00818 public:
00819         ScreenRGB32le(Size width, Size height) : Screen(width,height) {};
00820 
00821         virtual void paint(Drawable &d) const;
00822 };
00823 
00824 
00825 #ifdef SDL_MAJOR_VERSION
00826 
00840 class ScreenSDL : public Screen {
00841 protected:
00843         virtual void rgbToSurface(RGB color, void **pixel) { (void)color; (void)pixel; };
00844 
00846         virtual RGB surfaceToRGB(void *pixel) { (void)pixel; return 0; };
00847 
00849         SDL_Surface *surface;
00850         Uint32 start_abs_time,current_abs_time,current_time;
00851 
00853         int downx, downy;
00854 
00856         Ticks lastclick,lastdown;
00857 
00858 public:
00859 
00865         ScreenSDL(SDL_Surface *surface);
00866 
00873         void setSurface(SDL_Surface *surface) { this->surface = surface; }
00874 
00876         SDL_Surface *getSurface() { return surface; }
00877 
00879         virtual void paint(Drawable &d) const;
00880 
00882         Ticks update(Ticks ticks);
00883 
00885         bool event(const SDL_Event *ev) { return event(*ev); }
00886 
00887         void watchTime();
00888         Uint32 getTime() { return current_time; }
00889 
00891         bool event(const SDL_Event& ev);
00892 };
00893 #endif
00894 
00895 class Font;
00896 
00915 class Drawable {
00916 protected:
00917         friend Ticks Screen::update(void *, Ticks);
00919         RGB *const buffer;
00921         const int width;
00923         const int height;
00925         const bool owner;
00926 
00928         RGB color;
00930         const Font *font;
00932         int lineWidth;
00933 
00935         const int tx;
00937         const int ty;
00939         const int cx;
00941         const int cy;
00943         const int cw;
00945         const int ch;
00946 
00948         int x;
00950         int y;
00951 
00952 public:
00954 
00955         Drawable(int w, int h, RGB clear = Color::Transparent);
00956 
00958 
00962         Drawable(Drawable &src, RGB clear = 0);
00963 
00965         Drawable(Drawable &src, int x, int y, int w, int h);
00966 
00968         virtual ~Drawable();
00969 
00971         void clear(RGB clear = Color::Transparent);
00972 
00974 
00978         void setColor(RGB c) { color = c; };
00980         RGB getColor() { return color; };
00981 
00983         void setFont(const Font *f) { font = f; };
00985         const Font *getFont() { return font; };
00986 
00988         void setLineWidth(int w) { lineWidth = w; };
00990         int getLineWidth() { return lineWidth; };
00991 
00993         void gotoXY(int x, int y) { this->x = x; this->y = y; };
00995         int getX() { return x; }
00997         int getY() { return y; }
00998 
01000         int getClipX() { return cx; }
01002         int getClipY() { return cy; }
01004         int getClipWidth() { return cw; }
01006         int getClipHeight() { return ch; }
01007 
01009         void drawPixel() { if (x >= cx && x < cw && y >= cy && y < ch) buffer[x+tx+(y+ty)*width] = color; };
01011         void drawPixel(int x, int y) { gotoXY(x,y); drawPixel(); };
01012 
01014         RGB getPixel() { if (x >= cx && x < cw && y >= cy && y < ch) return buffer[x+tx+(y+ty)*width]; return Color::Transparent; };
01016         RGB getPixel(int x, int y) { gotoXY(x,y); return getPixel(); };
01017 
01019         void drawLine(int x2, int y2);
01021         void drawLine(int x1, int y1, int x2, int y2) { gotoXY(x1,y1); drawLine(x2,y2); };
01022 
01024 
01025         void drawCircle(int d);
01027 
01028         void drawCircle(int x, int y, int d) { gotoXY(x, y); drawCircle(d); };
01029 
01031 
01032         void drawRect(int w, int h);
01034 
01035         void drawRect(int x, int y, int w, int h) { gotoXY(x, y); drawRect(w, h); };
01036 
01038 
01040         void fill();
01042 
01043         void fill(int x, int y) { gotoXY(x,y); fill(); };
01044 
01046 
01047         void fillCircle(int d);
01049 
01050         void fillCircle(int x, int y, int d) { gotoXY(x, y); fillCircle(d); };
01051 
01053 
01054         void fillRect(int w, int h);
01056 
01057         void fillRect(int x, int y, int w, int h) { gotoXY(x, y); fillRect(w, h); };
01058 
01060 
01066         void drawText(const String& text, bool interpret = true, Size start = 0, Size len = (Size)-1);
01067 
01069 
01070         template <typename STR> void drawText(int x, int y, const STR text, bool interpret, Size start, Size len = (Size)-1) { gotoXY(x,y); drawText(String(text), interpret, start, len); }
01072 
01074         void drawText(const Char c, bool interpret = false);
01076 
01077         void drawText(int x, int y, const Char c, bool interpret = false) { gotoXY(x,y); drawText(c, interpret); }
01078 
01080 
01084         void drawDrawable(Drawable &d, unsigned char alpha = 1);
01086 
01088         void drawDrawable(int x, int y, Drawable &d, unsigned char alpha = 1) { gotoXY(x,y); drawDrawable(d, alpha); }
01089 
01090 };
01091 
01117 class Font {
01118 protected:
01119         friend void Drawable::drawText(const Char c, bool interpret);
01120         friend void Drawable::drawText(const String& s, bool interpret, Size start, Size len);
01121 
01123         struct ltstr { bool operator()(const char* s1, const char* s2) const {
01124                 return strcmp(s1, s2) < 0;
01125         } };
01127         static std::map<const char *,Font *,ltstr> registry;
01128 
01130         Font() {};
01131 
01133 
01135         virtual void drawChar(Drawable *d, const Char c) const = 0;
01136 
01138 
01139         virtual void drawString(Drawable *d, const String &s, Size start, Size len) const {
01140                 if (len > s.size()-start) len = (Size)(s.size()-start);
01141                 len += start;
01142                 while (start < len) drawChar(d,s[start++]);
01143         }
01144 
01145 public:
01147 
01148         static const Font *getFont(const char *name) {
01149                 std::map<const char *,Font *,ltstr>::iterator i = registry.find(name);
01150                 if (i == registry.end()) return(strcmp(name,"default")?getFont("default"):NULL);
01151                 return (*i).second;
01152         }
01153 
01154         static void registry_freeall() {
01155                 std::map<const char *,Font *,ltstr>::iterator it;
01156 
01157                 while ((it=registry.begin()) != registry.end()) {
01158                         delete it->second;
01159                         it->second = NULL;
01160                         registry.erase(it);
01161                 }
01162         }
01163 
01165 
01167         static void addFont(const char *name, Font *font) {
01168                 std::map<const char *,Font *,ltstr>::iterator i = registry.find(name);
01169                 if (i != registry.end()) delete (*i).second;
01170                 registry[name] = font;
01171         }
01172 
01173         virtual ~Font() {};
01174 
01176         virtual int getHeight() const = 0;
01177 
01179         virtual int getAscent() const = 0;
01180 
01182         template <typename STR> int getWidth(const STR s, Size start = 0, Size len = (Size)-1) const {
01183                 return this->getWidth(String(s), start, len);
01184         }
01185 
01187         virtual int getWidth(Char c = 'M') const = 0;
01188 
01190 
01191         virtual int getWidth(const String &s, Size start = 0, Size len = (Size)-1) const {
01192                 int width = 0;
01193                 if (start+len > s.size()) len = (Size)(s.size()-start);
01194                 while (len--) width += getWidth(s[start++]);
01195                 return width;
01196         }
01197 
01199         enum SpecialChar { CR = '\r', LF = '\n', BS = '\b', Tab = '\t', Space = ' ', ESC = 27 };
01200 
01202         virtual SpecialChar toSpecial(Char c) const { return (SpecialChar)(c<255?c:255); }
01203 
01205         virtual Char fromSpecial(SpecialChar c) const { return c; }
01206 };
01207 
01214 class BitmapFont : public Font {
01215 protected:
01217         const unsigned char *const bitmap;
01218 
01220         const int width;
01221 
01223         const int height;
01224 
01226         const int ascent;
01227 
01229         const int *const widths;
01230 
01232 
01233         const int *const ascents;
01234 
01236         const bool background_set;
01237 
01239         const int col_step;
01240 
01242         const int row_step;
01243 
01245 
01246         const int character_step;
01247 
01249         const unsigned char *const*const char_position;
01250 
01252 
01253         const SpecialChar *const special;
01254 
01256         const bool owner;
01257 
01259         const Char last;
01260 
01262 
01264         virtual void drawChar(Drawable *d, const Char c) const;
01265 
01266 public:
01268 
01271         BitmapFont(const unsigned char *data, int height, int ascent, bool owner = false,
01272                 int width = 8, bool background_set = false,
01273                 int col_step = -1, int row_step = 8, int character_step = 0, Char last = 256,
01274                 const int *widths = NULL, const int *ascents = NULL,
01275                 const unsigned char *const* char_position = NULL,
01276                 const SpecialChar *special = NULL);
01277 
01278         virtual ~BitmapFont();
01279 
01281         virtual int getHeight() const { return height; };
01282 
01284         virtual int getAscent() const { return ascent; };
01285 
01287         virtual int getWidth(Char c = 'M') const { return (widths != NULL?widths[c]:width); };
01288 
01290         virtual SpecialChar toSpecial(Char c) const { return (special != NULL?special[c]:Font::toSpecial(c)); }
01291 
01293         virtual Char fromSpecial(SpecialChar c) const { if (special == NULL) return Font::fromSpecial(c); Char i = 0; while(special[i] != c) i++; return i; }
01294 
01295 };
01296 
01297 class ActionEventSource;
01299 struct ActionEventSource_Callback {
01300 public:
01302 
01303                 virtual void actionExecuted(ActionEventSource *source, const String &arg) = 0;
01304                 virtual ~ActionEventSource_Callback() {}
01305 };
01306 
01308 
01313 class ActionEventSource {
01314 protected:
01316         std::list<ActionEventSource_Callback *> actionHandlers;
01317 
01319 
01321         String name;
01322 
01323 public:
01325         template <typename STR> ActionEventSource(const STR name) : name(String(name)) { }
01326 
01328         virtual ~ActionEventSource() {}
01329 
01331         void addActionHandler(ActionEventSource_Callback *handler) { actionHandlers.push_back(handler); }
01332 
01334         void removeActionHandler(ActionEventSource_Callback *handler) { actionHandlers.remove(handler); }
01335 
01337         template <typename STR> void setName(const STR name) { this->name = String(name); }
01338 
01340         const String &getName() const { return name; }
01341 
01343         void executeAction(const String &arg) {
01344                 std::list<ActionEventSource_Callback*>::iterator i = actionHandlers.begin();
01345                 bool end = (i == actionHandlers.end());
01346                 while (!end) {
01347                         ActionEventSource_Callback *c = *i;
01348                         ++i;
01349                         end = (i == actionHandlers.end());
01350                         c->actionExecuted(this,arg);
01351                 }
01352         }
01353 
01355         void executeAction() { executeAction(name); }
01356 };
01357 
01359 class BorderedWindow : public Window {
01360 protected:
01362         int border_left, border_top, border_right, border_bottom;
01363 
01365         BorderedWindow(Window *parent, int x, int y, int w, int h, int bl, int bt, int br, int bb) :
01366                 Window(parent,x,y,w,h), border_left(bl), border_top(bt), border_right(br), border_bottom(bb) {}
01367 
01368 public:
01369         virtual void paintAll(Drawable &d) const;
01370         virtual bool mouseMoved(int x, int y);
01371         virtual bool mouseDown(int x, int y, MouseButton button);
01372         virtual bool mouseDragged(int x, int y, MouseButton button);
01373         virtual int getScreenX() const { return Window::getScreenX()+border_left; }
01374         virtual int getScreenY() const { return Window::getScreenY()+border_top; }
01375 };
01376 
01378 
01382 class Label : public Window {
01384         const Font *font;
01385 
01387         RGB color;
01388 
01390         String text;
01391 
01393         bool interpret;
01394 
01395 public:
01397 
01398         template <typename STR> Label(Window *parent, int x, int y, const STR text, int width = 0, const Font *font = Font::getFont("default"), RGB color = Color::Text) :
01399                 Window(parent, x, y, (width?width:1), 1), font(font), color(color), text(text), interpret(width != 0)
01400         { resize(); }
01401 
01403         template <typename STR> void setText(const STR text) { this->text = text; resize(); }
01405         const String& getText() { return text; }
01406 
01408         void setFont(const Font *font) { this->font = font; resize(); }
01410         const Font *getFont() { return font; }
01411 
01413         void setColor(const RGB color) { this->color = color; resize(); }
01415         RGB getColor() { return color; }
01416 
01418         virtual void resize(int w = -1, int h = -1) {
01419         (void)h;//UNUSED
01420                 if (w == -1) w = (interpret?getWidth():0);
01421                 else interpret = (w != 0);
01422                 Drawable d((w?w:1), 1);
01423                 d.setFont(font);
01424                 d.drawText(0, font->getAscent(), text, interpret, 0);
01425                 if (interpret) Window::resize(w, d.getY()-font->getAscent()+font->getHeight());
01426                 else Window::resize(d.getX(), font->getHeight());
01427         }
01428 
01430         virtual void paint(Drawable &d) const { d.setColor(color); d.drawText(0, font->getAscent(), text, interpret, 0); }
01431 
01432         virtual bool raise() { return false; }
01433 };
01434 
01435 
01437 
01440 class Input : public Window, public Timer_Callback, public ActionEventSource {
01441 protected:
01443         String text;
01444 
01446         Size pos;
01447 
01449         Size lastpos;
01450 
01452         int posx, posy;
01453 
01455         Size start_sel, end_sel;
01456 
01458         bool blink;
01459 
01461         bool insert;
01462 
01464         bool multi;
01465 
01467         int offset;
01468 
01470         void checkOffset() {
01471                 if (lastpos == pos) return;
01472                 const Font *f = Font::getFont("input");
01473                 if (multi) {
01474                         Drawable d(width-6,1);
01475                         d.setFont(f);
01476                         d.drawText(0, 0, text, multi, 0, pos);
01477                         posy = d.getY();
01478                         posx = d.getX();
01479                         if (posy-offset > height-8-f->getHeight()) offset = posy-height+8+f->getHeight();
01480                         if (posy-offset < 0) offset = posy;
01481                 } else {
01482                         posy = 0;
01483                         posx = f->getWidth(text,0,pos);
01484                         if (f->getWidth(text,0,pos+1)-offset > width-10) offset = f->getWidth(text,0,pos+1)-width+10;
01485                         if (f->getWidth(text,0,(pos>0?pos-1:0))-offset < 0) offset = f->getWidth(text,0,(pos>0?pos-1:0));
01486                 }
01487                 lastpos = pos;
01488                 setDirty();
01489         }
01490 
01491 public:
01493         Input(Window *parent, int x, int y, int w, int h = 0) :
01494                 Window(parent,x,y,w,(h?h:Font::getFont("input")->getHeight()+10)), ActionEventSource("GUI::Input"),
01495                 text(""), pos(0), lastpos(0), posx(0), posy(0), start_sel(0), end_sel(0), blink(true), insert(true), multi(h != 0), offset(0)
01496         { Timer::add(this,30); }
01497 
01498         ~Input() {
01499                 Timer::remove(this);
01500         }
01501 
01503         virtual void paint(Drawable &d) const;
01504 
01506         void clearSelection() {
01507                 text.erase(text.begin()+(pos = imin(start_sel,end_sel)),text.begin()+imax(start_sel,end_sel));
01508                 start_sel = end_sel = pos;
01509         }
01510 
01512         void copySelection() {
01513                 setClipboard(String(text.begin()+imin(start_sel,end_sel),text.begin()+imax(start_sel,end_sel)));
01514         }
01515 
01517         void cutSelection() {
01518                 setClipboard(String(text.begin()+imin(start_sel,end_sel),text.begin()+imax(start_sel,end_sel)));
01519                 clearSelection();
01520         }
01521 
01523         void pasteSelection() {
01524                 String c = getClipboard();
01525                 clearSelection();
01526                 text.insert(text.begin()+pos,c.begin(),c.end());
01527                 start_sel = end_sel = pos += (Size)c.size();
01528         }
01529 
01531         Size findPos(int x, int y);
01532 
01534         template <typename STR> void setText(const STR text) { this->text = text; setDirty(); }
01536         const String& getText() { return text; };
01537 
01539         virtual bool keyDown(const Key &key);
01540 
01542         virtual bool mouseDown(int x, int y, MouseButton button);
01543 
01545         virtual bool mouseDragged(int x, int y, MouseButton button);
01546 
01548         virtual Ticks timerExpired(Ticks time)
01549         { (void)time; blink = !blink; setDirty(); return 30; }
01550 
01552         virtual void posToEnd(void);
01553 };
01554 
01555 class ToplevelWindow;
01557 struct ToplevelWindow_Callback {
01558 public:
01560 
01563                 virtual bool windowClosing(ToplevelWindow *win) = 0;
01564 
01566 
01570                 virtual void windowClosed(ToplevelWindow *win) = 0;
01571                 virtual ~ToplevelWindow_Callback() {}
01572 };
01573 
01575 class ToplevelWindow : public BorderedWindow, public ActionEventSource_Callback {
01576 protected:
01578         String title;
01579 
01581         int dragx, dragy;
01582 
01584         std::list<ToplevelWindow_Callback *> closehandlers;
01585 
01587         Menu *systemMenu;
01588 
01589 public:
01591         template <typename STR> ToplevelWindow(Screen *parent, int x, int y, int w, int h, const STR title);
01592 
01594         ~ToplevelWindow() {
01595                 std::list<ToplevelWindow_Callback*>::iterator i = closehandlers.begin();
01596                 bool end = (i == closehandlers.end());
01597                 while (!end) {
01598                         ToplevelWindow_Callback *c = *i;
01599                         ++i;
01600                         end = (i == closehandlers.end());
01601                         c->windowClosed(this);
01602                 }
01603         }
01604 
01606         virtual void actionExecuted(ActionEventSource *src, const String &item) {
01607         (void)src;
01608                 if (item == String("Close")) close();
01609         }
01610 
01612         void addCloseHandler(ToplevelWindow_Callback *handler) { closehandlers.push_back(handler); }
01613 
01615         void removeCloseHandler(ToplevelWindow_Callback *handler) { closehandlers.remove(handler); }
01616 
01617         virtual void paint(Drawable &d) const;
01618         virtual bool mouseDown(int x, int y, MouseButton button);
01619         virtual bool mouseDoubleClicked(int x, int y, MouseButton button);
01620         virtual bool mouseUp(int x, int y, MouseButton button) {
01621                 if (button == Left && dragx >= 0 && dragy >= 0) {
01622                         dragx = dragy = -1;
01623                         return true;
01624                 }
01625                 BorderedWindow::mouseUp(x,y,button);
01626                 return true;
01627         }
01628         virtual bool mouseDragged(int x, int y, MouseButton button) {
01629                 if (button == Left && dragx >= 0 && dragy >= 0) {
01630                         move(x-dragx+this->x,y-dragy+this->y);
01631                         return true;
01632                 }
01633                 BorderedWindow::mouseDragged(x,y,button);
01634                 return true;
01635         }
01636         virtual bool mouseMoved(int x, int y) {
01637                 BorderedWindow::mouseMoved(x,y);
01638                 return true;
01639         }
01640 
01642         virtual bool raise() {
01643                 Window *last = parent->children.back();
01644                 parent->children.remove(this);
01645                 parent->children.push_back(this);
01646                 if (last != this) {
01647                         focusChanged(true);
01648                         last->focusChanged(false);
01649                 }
01650                 return true;
01651         }
01652 
01654         template <typename STR> void setTitle(const STR title) { this->title = title; setDirty(); }
01656         const String& getTitle() { return title; }
01657 
01659         void close() {
01660                 bool doit = true;
01661                 std::list<ToplevelWindow_Callback*>::iterator i = closehandlers.begin();
01662                 bool end = (i == closehandlers.end());
01663                 while (!end) {
01664                         ToplevelWindow_Callback *c = *i;
01665                         ++i;
01666                         end = (i == closehandlers.end());
01667                         doit = doit && c->windowClosing(this);
01668                 }
01669                 if (doit) delete this;
01670         }
01671 };
01672 
01674 
01688 class TransientWindow : public Window, Window_Callback, ToplevelWindow_Callback {
01689 protected:
01691         Window *realparent;
01692 
01694         int relx, rely;
01695 
01696 public:
01698         virtual void focusChanged(bool gained) {
01699                 Window::focusChanged(gained);
01700                 if (isVisible() && !gained) {
01701                         if (realparent->hasFocus()) raise();
01702                         else setVisible(false);
01703                 }
01704         }
01705 
01707         void windowClosed(ToplevelWindow *win) {
01708         (void)win;
01709                 delete this;
01710         }
01711 
01713         bool windowClosing(ToplevelWindow *win) { (void)win; return true; }
01714 
01716 
01718         TransientWindow(Window *parent, int x, int y, int w, int h) :
01719                 Window(parent->getScreen(),x+parent->getScreenX(),y+parent->getScreenY(),w,h),
01720                 realparent(parent), relx(x), rely(y) {
01721                 Window *p = realparent, *last = NULL, *last2 = NULL;
01722                 while (p != NULL) {
01723                         p->addWindowHandler(this);
01724                         last2 = last;
01725                         last = p;
01726                         p = p->getParent();
01727                 }
01728                 dynamic_cast<ToplevelWindow *>(last2)->addCloseHandler(this);
01729         }
01730 
01731         ~TransientWindow() {
01732                 Window *p = realparent, *last = NULL, *last2 = NULL;
01733                 while (p != NULL) {
01734                         p->removeWindowHandler(this);
01735                         last2 = last;
01736                         last = p;
01737                         p = p->getParent();
01738                 }
01739                 dynamic_cast<ToplevelWindow *>(last2)->removeCloseHandler(this);
01740          }
01741 
01742         virtual void move(int x, int y) { relx = x; rely = y;
01743                 Window::move(x+realparent->getScreenX(),y+realparent->getScreenY()); }
01744         virtual int getX() const { return x-realparent->getScreenX(); }
01745         virtual int getY() const { return y-realparent->getScreenY(); }
01746         virtual void setVisible(bool v) { if (v) raise(); Window::setVisible(v); }
01747         virtual void windowMoved(Window *src, int x, int y) { (void)src; (void)x; (void)y; move(relx,rely); }
01748 
01750         virtual bool raise() {
01751                 Window *last = parent->children.back();
01752                 parent->children.remove(this);
01753                 parent->children.push_back(this);
01754                 if (last != this) {
01755                         focusChanged(true);
01756                         last->focusChanged(false);
01757                 }
01758                 return true;
01759         }
01760 
01761 };
01762 
01764 
01773 class Menu : public TransientWindow, public ActionEventSource {
01774 protected:
01776         std::vector<String> items;
01777 
01779 
01780         int selected;
01781 
01783         bool firstMouseUp;
01784 
01786         Window *mouseTakenFrom;
01787 
01789 
01790         virtual void selectItem(int x, int y) {
01791         (void)x;//UNUSED
01792                 y -= 2;
01793                 selected = -1;
01794                 const int height = Font::getFont("menu")->getHeight()+2;
01795                 std::vector<String>::iterator i;
01796                 for (i = items.begin(); i != items.end() && y > 0; ++i) {
01797                         selected++;
01798                         if ((*i).size() > 0) y -= height;
01799                         else y -= 12;
01800                 }
01801                 if (y > 0 || (selected >= 0 && items[(unsigned int)selected].size() == 0)) selected = -1;
01802         }
01803 
01804         virtual Size getPreferredWidth() {
01805                 Size width = 0;
01806                 const Font *f = Font::getFont("menu");
01807                 std::vector<String>::iterator i;
01808                 for (i = items.begin(); i != items.end() && y > 0; ++i) {
01809                         Size newwidth = (unsigned int)f->getWidth(*i);
01810                         if (newwidth > width) width = newwidth;
01811                 }
01812                 return width+39;
01813         }
01814 
01815         virtual Size getPreferredHeight() {
01816                 Size height = 0;
01817                 const Size h = (unsigned int)Font::getFont("menu")->getHeight()+2u;
01818                 std::vector<String>::iterator i;
01819                 for (i = items.begin(); i != items.end() && y > 0; ++i) {
01820                         height += ((*i).size() > 0?h:12);
01821                 }
01822                 return height+6;
01823         }
01824 
01825 public:
01827 
01829         template <typename STR> Menu(Window *parent, int x, int y, const STR name) :
01830                 TransientWindow(parent,x,y,4,4), ActionEventSource(name), selected(-1)
01831                 { setVisible(false); }
01832 
01833         ~Menu() {
01834                 setVisible(false);
01835         }
01836 
01838         virtual void paint(Drawable &d) const;
01839 
01841         virtual bool mouseMoved(int x, int y)  {
01842                 selectItem(x,y);
01843                 return true;
01844         }
01845 
01847         virtual bool mouseDragged(int x, int y, MouseButton button)  {
01848         (void)button;//UNUSED   
01849                 selectItem(x,y);
01850                 return true;
01851         }
01852 
01853         virtual bool mouseDown(int x, int y, MouseButton button)  {
01854         (void)button;//UNUSED
01855         (void)x;//UNUSED
01856         (void)y;//UNUSED        
01857         return true;
01858     }
01859 
01861         virtual bool mouseUp(int x, int y, MouseButton button)  {
01862         (void)button;//UNUSED
01863         
01864                 selectItem(x,y);
01865                 if (firstMouseUp) firstMouseUp = false;
01866                 else setVisible(false);
01867                 execute();
01868                 return true;
01869         }
01870 
01872         virtual bool keyDown(const Key &key) {
01873                 if (key.special == Key::Up) selected--;
01874                 else if (key.special == Key::Down) selected++;
01875                 else if (key.special == Key::Enter) { execute(); return true; }
01876                 else if (key.special == Key::Escape) { setVisible(false); return true; }
01877                 else return true;
01878                 if (items[(unsigned int)selected].size() == 0 && items.size() > 1) return keyDown(key);
01879                 if (selected < 0) selected = (int)(items.size()-1);
01880                 if (selected >= (int)items.size()) selected = 0;
01881                 return true;
01882         }
01883 
01884 
01886         template <typename T> void addItem(const T item) {
01887                 items.push_back(String(item));
01888                 resize((int)getPreferredWidth(),(int)getPreferredHeight());
01889         }
01890 
01892         template <typename T> void removeItem(const T item) {
01893                 const String s(item);
01894                 std::vector<String>::iterator i = items.begin();
01895                 while (i != items.end() && s != (*i)) ++i;
01896                 if (i != items.end()) items.erase(i);
01897                 resize(getPreferredWidth(),getPreferredHeight());
01898         }
01899 
01900         virtual void setVisible(bool v) {
01901                 TransientWindow::setVisible(v);
01902                 if (v) {
01903                         parent->mouseChild = this;
01904                         raise();
01905                         firstMouseUp = true;
01906                 }
01907         }
01908 
01910         void execute() {
01911                 if (selected >= 0) {
01912                         setVisible(false);
01913                         executeAction(items[(unsigned int)selected]);
01914                 }
01915         }
01916 };
01917 
01919 
01922 class Button : public BorderedWindow, public ActionEventSource {
01923 protected:
01925         bool pressed;
01926 
01927 public:
01929         Button(Window *parent, int x, int y, int w, int h) : BorderedWindow(parent,x,y,w,h,6,5,6,5), ActionEventSource("GUI::Button"), pressed(0) {}
01930 
01932 
01933         template <typename T> Button(Window *parent, int x, int y, const T text, int w = -1, int h = -1);
01934 
01936         virtual void paint(Drawable &d) const;
01937 
01939         virtual bool mouseDown(int x, int y, MouseButton button) {
01940         (void)button;//UNUSED
01941         (void)x;//UNUSED
01942         (void)y;//UNUSED
01943         
01944                 if (button == Left) {
01945                         border_left = 7; border_right = 5; border_top = 7; border_bottom = 3;
01946                         pressed = true;
01947                 }
01948                 return true;
01949         }
01950 
01952         virtual bool mouseUp(int x, int y, MouseButton button)  {
01953         (void)button;//UNUSED
01954         (void)x;//UNUSED
01955         (void)y;//UNUSED
01956         
01957                 if (button == Left) {
01958                         border_left = 6; border_right = 6; border_top = 5; border_bottom = 5;
01959                         pressed = false;
01960                 }
01961                 return true;
01962         }
01963 
01965         virtual bool mouseClicked(int x, int y, MouseButton button) {
01966         (void)button;//UNUSED
01967         (void)x;//UNUSED
01968         (void)y;//UNUSED
01969         
01970                 if (button == Left) {
01971                         executeAction();
01972                         return true;
01973                 }
01974                 return false;
01975         }
01976 
01978         virtual bool keyDown(const Key &key);
01979 
01981         virtual bool keyUp(const Key &key);
01982 
01983 };
01984 
01986 
01992 class Menubar : public Window, public ActionEventSource, ActionEventSource_Callback {
01993 protected:
01995         int selected;
01996 
01998         int lastx;
01999 
02001         std::vector<Menu*> menus;
02002 
02003 public:
02005 
02006         Menubar(Window *parent, int x, int y, int w) : Window(parent,x,y,w,Font::getFont("menu")->getHeight()+5), ActionEventSource("GUI::Menubar"), selected(-1), lastx(0) {}
02007 
02009         template <typename STR> void addMenu(const STR name) {
02010                 const String n(name);
02011                 menus.push_back(new Menu(this,lastx,height-2,n));
02012                 menus.back()->addActionHandler(this);
02013                 lastx += Font::getFont("menu")->getWidth(n)+14;
02014         }
02015 
02017         template <typename STR> void addItem(int index, const STR name) { menus[(unsigned int)index]->addItem(name); }
02018 
02020         template <typename STR> void removeItem(int index, const STR name) { menus[(unsigned int)index]->removeItem(name); }
02021 
02023         virtual void paint(Drawable &d) const;
02024 
02026         virtual bool mouseDown(int x, int y, MouseButton button) {
02027         (void)button;//UNUSED
02028         (void)y;//UNUSED
02029                 int oldselected = selected;
02030                 if (selected >= 0 && !menus[(unsigned int)selected]->isVisible()) oldselected = -1;
02031                 if (selected >= 0) menus[(unsigned int)selected]->setVisible(false);
02032                 if (x < 0 || x >= lastx) return true;
02033                 for (selected = (int)(menus.size()-1); menus[(unsigned int)selected]->getX() > x; selected--) {};
02034                 if (oldselected == selected) selected = -1;
02035                 else menus[(unsigned int)selected]->setVisible(true);
02036                 return true;
02037         }
02038 
02040         virtual bool keyDown(const Key &key) { (void)key; return true; }
02041 
02043         virtual bool keyUp(const Key &key) { (void)key; return true; }
02044 
02045         virtual void actionExecuted(ActionEventSource *src, const String &arg) {
02046                 std::list<ActionEventSource_Callback*>::iterator i = actionHandlers.begin();
02047                 bool end = (i == actionHandlers.end());
02048                 while (!end) {
02049                         ActionEventSource_Callback *c = *i;
02050                         ++i;
02051                         end = (i == actionHandlers.end());
02052                         c->actionExecuted(src,arg);
02053                 }
02054         }
02055 };
02056 
02058 
02061 class Checkbox : public BorderedWindow, public ActionEventSource {
02062 protected:
02064         bool checked;
02065 
02066 public:
02068         Checkbox(Window *parent, int x, int y, int w, int h) : BorderedWindow(parent,x,y,w,h,16,0,0,0), ActionEventSource("GUI::Checkbox"), checked(0) {}
02069 
02071 
02072         template <typename T> Checkbox(Window *parent, int x, int y, const T text, int w = -1, int h = -1);
02073 
02075         virtual void paint(Drawable &d) const;
02076 
02078         virtual void setChecked(bool checked) { this->checked = checked; }
02079 
02081         virtual bool isChecked() { return checked; }
02082 
02084         virtual bool mouseDown(int x, int y, MouseButton button) {
02085         (void)button;//UNUSED
02086         (void)x;//UNUSED
02087         (void)y;//UNUSED        
02088                 checked = !checked;
02089                 return true;
02090         }
02091 
02093         virtual bool mouseUp(int x, int y, MouseButton button)  {
02094         (void)button;//UNUSED
02095         (void)x;//UNUSED
02096         (void)y;//UNUSED        
02097                 execute();
02098                 return true;
02099         }
02100 
02102         virtual bool keyDown(const Key &key);
02103 
02105         virtual bool keyUp(const Key &key);
02106 
02108         virtual void execute() {
02109                 String arg(name);
02110                 if (!checked) arg.insert(arg.begin(),'!');
02111                 executeAction(arg);
02112         }
02113 };
02114 
02115 class Frame;
02116 
02118 
02121 class Radiobox : public BorderedWindow, public ActionEventSource {
02122 protected:
02124         bool checked;
02125 
02126 public:
02128         Radiobox(Frame *parent, int x, int y, int w, int h);
02129 
02131 
02132         template <typename T> Radiobox(Frame *parent, int x, int y, const T text, int w = -1, int h = -1);
02133 
02135         virtual void paint(Drawable &d) const;
02136 
02138         virtual void setChecked(bool checked) { this->checked = checked; }
02139 
02141         virtual bool isChecked() { return checked; }
02142 
02144         virtual bool mouseDown(int x, int y, MouseButton button) {
02145         (void)button;//UNUSED
02146         (void)x;//UNUSED
02147         (void)y;//UNUSED
02148         checked = true;
02149                 return true;
02150         }
02151 
02153         virtual bool mouseUp(int x, int y, MouseButton button)  {
02154         (void)button;//UNUSED
02155         (void)x;//UNUSED
02156         (void)y;//UNUSED
02157                 executeAction();
02158                 return true;
02159         }
02160 
02162         virtual bool keyDown(const Key &key);
02163 
02165         virtual bool keyUp(const Key &key);
02166 };
02167 
02169 
02171 class Frame : public BorderedWindow, public ActionEventSource, protected ActionEventSource_Callback {
02172 protected:
02173         friend class Radiobox;
02174 
02176         int selected;
02177 
02179         String label;
02180 
02182         virtual void actionExecuted(ActionEventSource *src, const String &arg) {
02183         (void)arg;//UNUSED
02184                 for (std::list<Window *>::iterator i = children.begin(); i != children.end(); ++i) {
02185                         Radiobox *r = dynamic_cast<Radiobox*>(*i);
02186                         if (r != NULL && src != dynamic_cast<ActionEventSource*>(r)) r->setChecked(false);
02187                 }
02188                 executeAction(src->getName());
02189         }
02190 
02191 public:
02193         Frame(Window *parent, int x, int y, int w, int h) : BorderedWindow(parent,x,y,w,h,5,5,5,5), ActionEventSource("GUI::Frame"), selected(0) {}
02194 
02196         template <typename T> Frame(Window *parent, int x, int y, int w, int h, const T text) :
02197                 BorderedWindow(parent,x,y,w,h,5,Font::getFont("default")->getHeight()+2,5,5),
02198                 ActionEventSource(text), selected(0), label(text) { }
02199 
02201         virtual void paint(Drawable &d) const;
02202 
02203 };
02204 
02206 class MessageBox2 : public GUI::ToplevelWindow {
02207 protected:
02208         Label *message;
02209         Button *close;
02210 public:
02212         template <typename STR> MessageBox2(Screen *parent, int x, int y, int width, const STR title, const STR text) :
02213                 ToplevelWindow(parent, x, y, width, 1, title) {
02214                 message = new Label(this, 5, 5, text, width-10);
02215                 close = new GUI::Button(this, width/2-40, 10, "Close", 70);
02216                 close->addActionHandler(this);
02217                 setText(text);
02218         }
02219 
02221         template <typename STR> void setText(const STR text) {
02222                 message->setText(text);
02223                 close->move(width/2-40, 20+message->getHeight());
02224                 resize(width, message->getHeight()+100);
02225         }
02226 };
02227 
02228 template <typename STR> ToplevelWindow::ToplevelWindow(Screen *parent, int x, int y, int w, int h, const STR title) :
02229         BorderedWindow(parent, x, y, w, h, 6, 33, 6, 3), title(title),
02230         dragx(-1), dragy(-1), closehandlers(), systemMenu(new Menu(this,-1,-2,"System Menu")) {
02231 /* If these commands don't do anything, then why have them there?? --J.C. */
02232 #if 0 /* TODO: Allow selective enabling these if the Window object wants us to */
02233         systemMenu->addItem("Move");
02234         systemMenu->addItem("Resize");
02235         systemMenu->addItem("");
02236         systemMenu->addItem("Minimize");
02237         systemMenu->addItem("Maximize");
02238         systemMenu->addItem("Restore");
02239         systemMenu->addItem("");
02240 #endif
02241         systemMenu->addItem("Close");
02242         systemMenu->addActionHandler(this);
02243 }
02244 
02245 template <typename STR> Button::Button(Window *parent, int x, int y, const STR text, int w, int h) :
02246         BorderedWindow(parent,x,y,w,h,6,5,6,5), ActionEventSource(text), pressed(0)
02247 {
02248 
02249         Label *l = new Label(this,0,0,text);
02250         if (width < 0) resize(l->getWidth()+border_left+border_right+10,height);
02251         if (height < 0) resize(width,l->getHeight()+border_top+border_bottom+6);
02252         l->move((width-border_left-border_right-l->getWidth())/2,
02253                 (height-border_top-border_bottom-l->getHeight())/2);
02254 }
02255 
02256 template <typename STR> Checkbox::Checkbox(Window *parent, int x, int y, const STR text, int w, int h) :
02257         BorderedWindow(parent,x,y,w,h,16,0,0,0), ActionEventSource(text), checked(0)
02258 {
02259         Label *l = new Label(this,0,0,text);
02260         if (width < 0) resize(l->getWidth()+border_left+border_right+4,height);
02261         if (height < 0) resize(width,l->getHeight()+border_top+border_bottom+4);
02262         l->move((width-border_left-border_right-l->getWidth())/2,
02263                 (height-border_top-border_bottom-l->getHeight())/2);
02264 }
02265 
02266 template <typename STR> Radiobox::Radiobox(Frame *parent, int x, int y, const STR text, int w, int h) :
02267         BorderedWindow(parent,x,y,w,h,16,0,0,0), ActionEventSource(text), checked(0)
02268 {
02269         Label *l = new Label(this,0,0,text);
02270         if (width < 0) resize(l->getWidth()+border_left+border_right+4,height);
02271         if (height < 0) resize(width,l->getHeight()+border_top+border_bottom+4);
02272         l->move((width-border_left-border_right-l->getWidth())/2,
02273                 (height-border_top-border_bottom-l->getHeight())/2);
02274         addActionHandler(parent);
02275 }
02276 
02277 }
02278 
02279 #endif