window_gui.h

Go to the documentation of this file.
00001 /* $Id: window_gui.h 14466 2008-10-14 19:27:08Z rubidium $ */
00002 
00005 #ifndef WINDOW_GUI_H
00006 #define WINDOW_GUI_H
00007 
00008 #include "core/bitmath_func.hpp"
00009 #include "core/geometry_type.hpp"
00010 #include "vehicle_type.h"
00011 #include "viewport_type.h"
00012 #include "company_type.h"
00013 #include "strings_type.h"
00014 #include "core/alloc_type.hpp"
00015 #include "window_type.h"
00016 #include "tile_type.h"
00017 
00021 static const int MAX_NUMBER_OF_WINDOWS = 25;
00022 
00023 /* How the resize system works:
00024     First, you need to add a WWT_RESIZEBOX to the widgets, and you need
00025      to add the flag WDF_RESIZABLE to the window. Now the window is ready
00026      to resize itself.
00027     As you may have noticed, all widgets have a RESIZE_XXX in their line.
00028      This lines controls how the widgets behave on resize. RESIZE_NONE means
00029      it doesn't do anything. Any other option let's one of the borders
00030      move with the changed width/height. So if a widget has
00031      RESIZE_RIGHT, and the window is made 5 pixels wider by the user,
00032      the right of the window will also be made 5 pixels wider.
00033     Now, what if you want to clamp a widget to the bottom? Give it the flag
00034      RESIZE_TB. This is RESIZE_TOP + RESIZE_BOTTOM. Now if the window gets
00035      5 pixels bigger, both the top and bottom gets 5 bigger, so the whole
00036      widgets moves downwards without resizing, and appears to be clamped
00037      to the bottom. Nice aint it?
00038    You should know one more thing about this system. Most windows can't
00039     handle an increase of 1 pixel. So there is a step function, which
00040     let the windowsize only be changed by X pixels. You configure this
00041     after making the window, like this:
00042       w->resize.step_height = 10;
00043     Now the window will only change in height in steps of 10.
00044    You can also give a minimum width and height. The default value is
00045     the default height/width of the window itself. You can change this
00046     AFTER window - creation, with:
00047      w->resize.width or w->resize.height.
00048    That was all.. good luck, and enjoy :) -- TrueLight */
00049 
00050 enum ResizeFlag {
00051   RESIZE_NONE   = 0,  
00052 
00053   RESIZE_LEFT   = 1,  
00054   RESIZE_RIGHT  = 2,  
00055   RESIZE_TOP    = 4,  
00056   RESIZE_BOTTOM = 8,  
00057 
00058   RESIZE_LR     = RESIZE_LEFT  | RESIZE_RIGHT,   
00059   RESIZE_RB     = RESIZE_RIGHT | RESIZE_BOTTOM,  
00060   RESIZE_TB     = RESIZE_TOP   | RESIZE_BOTTOM,  
00061   RESIZE_LRB    = RESIZE_LEFT  | RESIZE_RIGHT  | RESIZE_BOTTOM, 
00062   RESIZE_LRTB   = RESIZE_LEFT  | RESIZE_RIGHT  | RESIZE_TOP | RESIZE_BOTTOM,  
00063   RESIZE_RTB    = RESIZE_RIGHT | RESIZE_TOP    | RESIZE_BOTTOM, 
00064 
00065   /* The following flags are used by the system to specify what is disabled, hidden, or clicked
00066    * They are used in the same place as the above RESIZE_x flags, Widget visual_flags.
00067    * These states are used in exceptions. If nothing is specified, they will indicate
00068    * Enabled, visible or unclicked widgets*/
00069   WIDG_DISABLED = 4,  
00070   WIDG_HIDDEN   = 5,  
00071   WIDG_LOWERED  = 6,  
00072 };
00073 
00074 enum {
00075   WIDGET_LIST_END = -1, 
00076 };
00077 
00081 struct Widget {
00082   byte type;                        
00083   byte display_flags;               
00084   byte color;                       
00085   int16 left;                       
00086   int16 right;                      
00087   int16 top;                        
00088   int16 bottom;                     
00089   uint16 data;                      
00090   StringID tooltips;                
00091 };
00092 
00096 enum FrameFlags {
00097   FR_NONE         =  0,
00098   FR_TRANSPARENT  =  1 << 0,  
00099   FR_BORDERONLY   =  1 << 4,  
00100   FR_LOWERED      =  1 << 5,  
00101   FR_DARKENED     =  1 << 6,  
00102 };
00103 
00104 DECLARE_ENUM_AS_BIT_SET(FrameFlags);
00105 
00106 /* wiget.cpp */
00107 void DrawFrameRect(int left, int top, int right, int bottom, int color, FrameFlags flags);
00108 
00112 struct WindowDesc {
00113   int16 left;             
00114   int16 top;              
00115   int16 minimum_width;    
00116   int16 minimum_height;   
00117   int16 default_width;    
00118   int16 default_height;   
00119   WindowClass cls;        
00120   WindowClass parent_cls; 
00121   uint32 flags;           
00122   const Widget *widgets;  
00123 };
00124 
00128 enum WindowDefaultFlag {
00129   WDF_STD_TOOLTIPS    =   1 << 0, 
00130   WDF_DEF_WIDGET      =   1 << 1, 
00131   WDF_STD_BTN         =   1 << 2, 
00132 
00133   WDF_UNCLICK_BUTTONS =   1 << 4, 
00134   WDF_STICKY_BUTTON   =   1 << 5, 
00135   WDF_RESIZABLE       =   1 << 6, 
00136   WDF_MODAL           =   1 << 7, 
00137 };
00138 
00142 enum WindowDefaultPosition {
00143   WDP_AUTO      = -1, 
00144   WDP_CENTER    = -2, 
00145   WDP_ALIGN_TBR = -3, 
00146   WDP_ALIGN_TBL = -4, 
00147 };
00148 
00152 struct Scrollbar {
00153   uint16 count;  
00154   uint16 cap;    
00155   uint16 pos;    
00156 };
00157 
00161 struct ResizeInfo {
00162   uint width;       
00163   uint height;      
00164   uint step_width;  
00165   uint step_height; 
00166 };
00167 
00168 enum SortButtonState {
00169   SBS_OFF,
00170   SBS_DOWN,
00171   SBS_UP,
00172 };
00173 
00177 struct ViewportData : ViewPort {
00178   VehicleID follow_vehicle;
00179   int32 scrollpos_x;
00180   int32 scrollpos_y;
00181   int32 dest_scrollpos_x;
00182   int32 dest_scrollpos_y;
00183 };
00184 
00188 struct Window : ZeroedMemoryAllocator {
00190   enum EventState {
00191     ES_HANDLED,     
00192     ES_NOT_HANDLED, 
00193   };
00194 
00195 protected:
00196   void Initialize(int x, int y, int min_width, int min_height,
00197       WindowClass cls, const Widget *widget, int window_number);
00198   void FindWindowPlacementAndResize(int def_width, int def_height);
00199   void FindWindowPlacementAndResize(const WindowDesc *desc);
00200 
00201 public:
00202   Window(int x, int y, int width, int height, WindowClass cls, const Widget *widget);
00203   Window(const WindowDesc *desc, WindowNumber number = 0);
00204 
00205   virtual ~Window();
00206 
00207   uint16 flags4;              
00208   WindowClass window_class;   
00209   WindowNumber window_number; 
00210 
00211   int left;   
00212   int top;    
00213   int width;  
00214   int height; 
00215 
00216   Scrollbar hscroll;  
00217   Scrollbar vscroll;  
00218   Scrollbar vscroll2; 
00219   ResizeInfo resize;  
00220 
00221   byte caption_color; 
00222 
00223   ViewportData *viewport;      
00224   Widget *widget;        
00225   uint widget_count;     
00226   uint32 desc_flags;     
00227 
00228   Window *parent;        
00229 
00230   void HandleButtonClick(byte widget);
00231 
00232   void SetWidgetDisabledState(byte widget_index, bool disab_stat);
00233   void DisableWidget(byte widget_index);
00234   void EnableWidget(byte widget_index);
00235   bool IsWidgetDisabled(byte widget_index) const;
00236   void SetWidgetHiddenState(byte widget_index, bool hidden_stat);
00237   void HideWidget(byte widget_index);
00238   void ShowWidget(byte widget_index);
00239   bool IsWidgetHidden(byte widget_index) const;
00240   void SetWidgetLoweredState(byte widget_index, bool lowered_stat);
00241   void ToggleWidgetLoweredState(byte widget_index);
00242   void LowerWidget(byte widget_index);
00243   void RaiseWidget(byte widget_index);
00244   bool IsWidgetLowered(byte widget_index) const;
00245   void AlignWidgetRight(byte widget_index_a, byte widget_index_b);
00246   int  GetWidgetWidth(byte widget_index) const;
00247 
00248   void RaiseButtons();
00249   void CDECL SetWidgetsDisabledState(bool disab_stat, int widgets, ...);
00250   void CDECL SetWidgetsHiddenState(bool hidden_stat, int widgets, ...);
00251   void CDECL SetWidgetsLoweredState(bool lowered_stat, int widgets, ...);
00252   void InvalidateWidget(byte widget_index) const;
00253 
00254   void DrawWidgets() const;
00255   void DrawViewport() const;
00256   void DrawSortButtonState(int widget, SortButtonState state) const;
00257 
00258   void DeleteChildWindows() const;
00259 
00260   void SetDirty() const;
00261 
00262   /*** Event handling ***/
00263 
00267   virtual void OnPaint() {}
00268 
00269 
00277   virtual EventState OnKeyPress(uint16 key, uint16 keycode) { return ES_NOT_HANDLED; }
00278 
00284   virtual EventState OnCTRLStateChange() { return ES_NOT_HANDLED; }
00285 
00286 
00292   virtual void OnClick(Point pt, int widget) {}
00293 
00299   virtual void OnDoubleClick(Point pt, int widget) {}
00300 
00306   virtual void OnRightClick(Point pt, int widget) {}
00307 
00313   virtual void OnDragDrop(Point pt, int widget) {}
00314 
00319   virtual void OnScroll(Point delta) {}
00320 
00327   virtual void OnMouseOver(Point pt, int widget) {}
00328 
00333   virtual void OnMouseWheel(int wheel) {}
00334 
00335 
00339   virtual void OnMouseLoop() {}
00340 
00344   virtual void OnTick() {}
00345 
00349   virtual void OnHundredthTick() {}
00350 
00354   virtual void OnTimeout() {}
00355 
00356 
00362   virtual void OnResize(Point new_size, Point delta) {}
00363 
00369   virtual void OnDropdownSelect(int widget, int index) {}
00370 
00376   virtual void OnQueryTextFinished(char *str) {}
00377 
00382   virtual void OnInvalidateData(int data = 0) {}
00383 
00384 
00391   virtual void OnPlaceObject(Point pt, TileIndex tile) {}
00392 
00396   virtual void OnPlaceObjectAbort() {}
00397 
00398 
00406   virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) {}
00407 
00417   virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) {}
00418 
00426   virtual void OnPlacePresize(Point pt, TileIndex tile) {}
00427 
00428   /*** End of the event handling ***/
00429 };
00430 
00434 class PickerWindowBase : public Window {
00435 
00436 public:
00437   PickerWindowBase(const WindowDesc *desc, Window *parent) : Window(desc)
00438   {
00439     this->parent = parent;
00440   };
00441 
00442   virtual ~PickerWindowBase();
00443 };
00444 
00445 /****************** THESE ARE NOT WIDGET TYPES!!!!! *******************/
00446 enum WindowWidgetBehaviours {
00447   WWB_PUSHBUTTON  = 1 << 5,
00448 
00449   WWB_MASK        = 0xE0,
00450 };
00451 
00452 
00456 enum WindowWidgetTypes {
00457   WWT_EMPTY,      
00458 
00459   WWT_PANEL,      
00460   WWT_INSET,      
00461   WWT_IMGBTN,     
00462   WWT_IMGBTN_2,   
00463 
00464   WWT_TEXTBTN,    
00465   WWT_TEXTBTN_2,  
00466   WWT_LABEL,      
00467   WWT_TEXT,       
00468   WWT_MATRIX,     
00469   WWT_SCROLLBAR,  
00470   WWT_FRAME,      
00471   WWT_CAPTION,    
00472 
00473   WWT_HSCROLLBAR, 
00474   WWT_STICKYBOX,  
00475   WWT_SCROLL2BAR, 
00476   WWT_RESIZEBOX,  
00477   WWT_CLOSEBOX,   
00478   WWT_DROPDOWN,   
00479   WWT_DROPDOWNIN, 
00480   WWT_EDITBOX,    
00481   WWT_LAST,       
00482 
00483   WWT_MASK = 0x1F,
00484 
00485   WWT_PUSHBTN     = WWT_PANEL   | WWB_PUSHBUTTON,
00486   WWT_PUSHTXTBTN  = WWT_TEXTBTN | WWB_PUSHBUTTON,
00487   WWT_PUSHIMGBTN  = WWT_IMGBTN  | WWB_PUSHBUTTON,
00488 };
00489 
00491 #define WIDGETS_END WWT_LAST,   RESIZE_NONE,     0,     0,     0,     0,     0, 0, STR_NULL
00492 
00496 enum WindowFlags {
00497   WF_TIMEOUT_TRIGGER   = 1,       
00498   WF_TIMEOUT_BEGIN     = 7,       
00499   WF_TIMEOUT_MASK      = 7,       
00500   WF_DRAGGING          = 1 <<  3, 
00501   WF_SCROLL_UP         = 1 <<  4, 
00502   WF_SCROLL_DOWN       = 1 <<  5, 
00503   WF_SCROLL_MIDDLE     = 1 <<  6, 
00504   WF_HSCROLL           = 1 <<  7,
00505   WF_SIZING            = 1 <<  8,
00506   WF_STICKY            = 1 <<  9, 
00507 
00508   WF_DISABLE_VP_SCROLL = 1 << 10, 
00509 
00510   WF_WHITE_BORDER_ONE  = 1 << 11,
00511   WF_WHITE_BORDER_MASK = 1 << 12 | WF_WHITE_BORDER_ONE,
00512   WF_SCROLL2           = 1 << 13,
00513 };
00514 
00515 Window *BringWindowToFrontById(WindowClass cls, WindowNumber number);
00516 Window *FindWindowFromPt(int x, int y);
00517 
00524 template <typename Wcls>
00525 Wcls *AllocateWindowDescFront(const WindowDesc *desc, int window_number)
00526 {
00527   if (BringWindowToFrontById(desc->cls, window_number)) return NULL;
00528   return new Wcls(desc, window_number);
00529 }
00530 
00531 void RelocateAllWindows(int neww, int newh);
00532 
00533 /* misc_gui.cpp */
00534 void GuiShowTooltips(StringID str, uint paramcount = 0, const uint64 params[] = NULL, bool use_left_mouse_button = false);
00535 
00536 /* widget.cpp */
00537 int GetWidgetFromPos(const Window *w, int x, int y);
00538 
00539 /* window.cpp */
00540 extern Window *_z_windows[];
00541 extern Window **_last_z_window;
00542 
00544 #define FOR_ALL_WINDOWS(wz) for (wz = _z_windows; wz != _last_z_window; wz++)
00545 
00551 enum {
00552   SCROLL_CON  = 0,
00553   SCROLL_EDIT = 1,
00554   SCROLL_SAVE = 2,
00555   SCROLL_CHAT = 4,
00556 };
00557 
00559 extern byte _no_scroll;
00560 
00561 extern Point _cursorpos_drag_start;
00562 
00563 extern int _scrollbar_start_pos;
00564 extern int _scrollbar_size;
00565 extern byte _scroller_click_timeout;
00566 
00567 extern bool _scrolling_scrollbar;
00568 extern bool _scrolling_viewport;
00569 
00570 extern byte _special_mouse_mode;
00571 enum SpecialMouseMode {
00572   WSM_NONE     = 0,
00573   WSM_DRAGDROP = 1,
00574   WSM_SIZING   = 2,
00575   WSM_PRESIZE  = 3,
00576 };
00577 
00578 Window *GetCallbackWnd();
00579 Window **FindWindowZPosition(const Window *w);
00580 
00581 void ScrollbarClickHandler(Window *w, const Widget *wi, int x, int y);
00582 
00583 void ResizeButtons(Window *w, byte left, byte right);
00584 
00585 void ResizeWindowForWidget(Window *w, uint widget, int delta_x, int delta_y);
00586 
00587 void SetVScrollCount(Window *w, int num);
00588 void SetVScroll2Count(Window *w, int num);
00589 void SetHScrollCount(Window *w, int num);
00590 
00591 
00599 inline void Window::SetWidgetDisabledState(byte widget_index, bool disab_stat)
00600 {
00601   assert(widget_index < this->widget_count);
00602   SB(this->widget[widget_index].display_flags, WIDG_DISABLED, 1, !!disab_stat);
00603 }
00604 
00609 inline void Window::DisableWidget(byte widget_index)
00610 {
00611   SetWidgetDisabledState(widget_index, true);
00612 }
00613 
00618 inline void Window::EnableWidget(byte widget_index)
00619 {
00620   SetWidgetDisabledState(widget_index, false);
00621 }
00622 
00628 inline bool Window::IsWidgetDisabled(byte widget_index) const
00629 {
00630   assert(widget_index < this->widget_count);
00631   return HasBit(this->widget[widget_index].display_flags, WIDG_DISABLED);
00632 }
00633 
00641 inline void Window::SetWidgetHiddenState(byte widget_index, bool hidden_stat)
00642 {
00643   assert(widget_index < this->widget_count);
00644   SB(this->widget[widget_index].display_flags, WIDG_HIDDEN, 1, !!hidden_stat);
00645 }
00646 
00651 inline void Window::HideWidget(byte widget_index)
00652 {
00653   SetWidgetHiddenState(widget_index, true);
00654 }
00655 
00660 inline void Window::ShowWidget(byte widget_index)
00661 {
00662   SetWidgetHiddenState(widget_index, false);
00663 }
00664 
00670 inline bool Window::IsWidgetHidden(byte widget_index) const
00671 {
00672   assert(widget_index < this->widget_count);
00673   return HasBit(this->widget[widget_index].display_flags, WIDG_HIDDEN);
00674 }
00675 
00681 inline void Window::SetWidgetLoweredState(byte widget_index, bool lowered_stat)
00682 {
00683   assert(widget_index < this->widget_count);
00684   SB(this->widget[widget_index].display_flags, WIDG_LOWERED, 1, !!lowered_stat);
00685 }
00686 
00691 inline void Window::ToggleWidgetLoweredState(byte widget_index)
00692 {
00693   assert(widget_index < this->widget_count);
00694   ToggleBit(this->widget[widget_index].display_flags, WIDG_LOWERED);
00695 }
00696 
00701 inline void Window::LowerWidget(byte widget_index)
00702 {
00703   SetWidgetLoweredState(widget_index, true);
00704 }
00705 
00710 inline void Window::RaiseWidget(byte widget_index)
00711 {
00712   SetWidgetLoweredState(widget_index, false);
00713 }
00714 
00720 inline bool Window::IsWidgetLowered(byte widget_index) const
00721 {
00722   assert(widget_index < this->widget_count);
00723   return HasBit(this->widget[widget_index].display_flags, WIDG_LOWERED);
00724 }
00725 
00731 inline void Window::AlignWidgetRight(byte widget_index_a, byte widget_index_b)
00732 {
00733   assert(widget_index_a < this->widget_count);
00734   assert(widget_index_b < this->widget_count);
00735   int w = this->widget[widget_index_a].right - this->widget[widget_index_a].left;
00736   this->widget[widget_index_a].right = this->widget[widget_index_b].left - 1;
00737   this->widget[widget_index_a].left  = this->widget[widget_index_a].right - w;
00738 }
00739 
00745 inline int Window::GetWidgetWidth(byte widget_index) const
00746 {
00747   assert(widget_index < this->widget_count);
00748   return this->widget[widget_index].right - this->widget[widget_index].left + 1;
00749 }
00750 
00751 #endif /* WINDOW_GUI_H */

Generated on Wed Nov 19 19:01:43 2008 for openttd by  doxygen 1.5.6