1 2 // menu.h 3 4 // Copyright 2004-2006 Jasmine Langridge, jas@jareiko.net 5 // License: GPL version 2 (see included gpl.txt) 6 7 8 /* 9 10 The organisation of this is horrible, I'm afraid... the menu.* files 11 contain both menu GUI implementation and level progress logic for 12 the game. Ick. 13 14 */ 15 16 // TODO: use enums instead of macros 17 18 // menus 19 #define AM_TOP 21 // Event / Practice / Single race / Quit 20 #define AM_TOP_EVT 22 // Choose event to race 21 #define AM_TOP_EVT_PREP 23 // Shows event progress 22 #define AM_TOP_EVT_ABANDON 24 // Really leave event? 23 #define AM_TOP_PRAC 25 // Choose event to practice 24 #define AM_TOP_PRAC_SEL 26 // Choose level to practice 25 #define AM_TOP_PRAC_SEL_PREP 27 // Show track info (practice) 26 #define AM_TOP_LVL 28 // Choose single race 27 #define AM_TOP_LVL_PREP 29 // Show track info (single race) 28 #define AM_TOP_QUIT 30 // Are you sure you want to quit? 29 #define AM_TOP_LVL_TIMES 31 // Show best times for Single level 30 #define AM_TOP_PRAC_TIMES 32 // Show best times for Practice level 31 #define AM_TOP_LVL_BTIMES 33 // Show best times for Single level (button) 32 #define AM_TOP_PRAC_BTIMES 34 // Show best times for Practice level (button) 33 34 // actions 35 #define AA_INIT 1 36 #define AA_RESUME 2 37 #define AA_GO_TOP 11 38 #define AA_GO_EVT 21 39 #define AA_PICK_EVT 22 40 #define AA_START_EVT 23 41 #define AA_RESUME_EVT 24 42 #define AA_RESTART_EVT 25 43 #define AA_GO_PRAC 31 44 #define AA_PICK_PRAC 32 45 #define AA_PICK_PRAC_LVL 33 46 #define AA_START_PRAC 34 47 #define AA_GO_LVL 41 48 #define AA_PICK_LVL 42 49 #define AA_START_LVL 43 50 #define AA_GO_QUIT 51 51 #define AA_QUIT_CONFIRM 52 52 #define AA_SHOWTIMES_LVL 61 53 #define AA_SHOWTIMES_PRAC 62 54 #define AA_BSHOWTIMES_LVL 63 // "Best Times" button pressed: show times with no highlight 55 #define AA_BSHOWTIMES_PRAC 64 56 57 // best times table actions for columns 58 #define AA_SORT_BY_PLAYERNAME 1001 59 #define AA_SORT_BY_CARNAME 1002 60 #define AA_SORT_BY_CARCLASS 1003 61 #define AA_SORT_BY_TOTALTIME 1004 62 63 64 /// used to determine which colors to use for the GuiWidget label 65 enum class LabelStyle 66 { 67 Regular, 68 Weak, 69 Strong, 70 Marked, 71 Header, 72 List 73 }; 74 75 /// used to determine which colors to use for the GuiWidget graphic 76 enum class GraphicStyle 77 { 78 Button, 79 Image 80 }; 81 82 struct GuiWidgetColors 83 { 84 vec4f normal; ///< non-clickable labels 85 vec4f click; ///< clickable labels 86 vec4f hover; ///< clickable labels with mouse hovering on top 87 vec4f listnormal; ///< non-clickable list items 88 vec4f listclick; ///< clickable list items 89 vec4f listhover; ///< clickable list items with mouse hovering on top 90 vec4f weak; ///< non-clickable labels that should be discreet 91 vec4f strong; ///< non-clickable labels that should be obvious 92 vec4f marked; ///< non-clickable labels that should draw attention 93 vec4f header; ///< non-clickable labels that are used as section title 94 vec4f bnormal; ///< disabled button 95 vec4f bclick; ///< clickable button 96 vec4f bhover; ///< clickable button with mouse hovering on top 97 GuiWidgetColorsGuiWidgetColors98 GuiWidgetColors(): 99 normal {1, 0, 0, 1}, 100 click {0, 1, 0, 1}, 101 hover {0, 0, 1, 1}, 102 listnormal {1, 1, 0, 1}, 103 listclick {1, 0, 1, 1}, 104 listhover {0, 1, 1, 1}, 105 weak {0.5, 0.5, 0.5, 1}, 106 strong {1, 1, 1, 1}, 107 marked {1, 0.5, 0.5, 1}, 108 header {0.8, 0.8, 0.4, 1}, 109 bnormal {1, 1, 0, 0.75}, 110 bclick {0, 1, 1, 0.75}, 111 bhover {1, 1, 1, 1} 112 { 113 } 114 }; 115 116 struct LevelState { 117 118 int state; 119 120 int currentevent; 121 int currentlevel; 122 int currentplayer; // current player in the best times list 123 124 int livesleft; 125 float totaltime; 126 127 std::vector<float> leveltimes; 128 }; 129 130 131 #define GWT_FREE 0 132 #define GWT_CONTAINER 10 133 #define GWT_FILLER 11 134 #define GWT_LABEL 12 135 #define GWT_GRAPHIC 13 136 137 #define GWPARENT_NONE -1 138 139 struct GuiWidget { 140 141 int type; 142 143 bool clickable; 144 int d1, d2; 145 146 std::string text; 147 float fontsize; 148 149 vec2f 150 dims_min, 151 pos; 152 153 vec4f 154 colnormal {1.00f, 1.00f, 1.00f, 0.85f}, ///< Normal color for unclickable widgets. 155 colclick {0.65f, 1.00f, 0.65f, 0.85f}, ///< Normal color for clickable widgets. 156 colhover {1.00f, 0.40f, 0.00f, 1.00f}; ///< Mouse hover color for clickable widgets. 157 158 float glow; 159 160 PTexture *tex; 161 GuiWidgetGuiWidget162 GuiWidget(int t) : type(t), clickable(false), d1(0), d2(0), glow(0.0f) { } 163 }; 164 165 166 class Gui { 167 168 private: 169 170 GuiWidgetColors colors; 171 172 std::vector<GuiWidget> widget; 173 174 PSSRender *ssRender; 175 176 vec2f cursor; 177 178 int highlight, defwidget; 179 180 float defflash; 181 182 PTexture *fonttex; 183 184 protected: 185 int getFreeWidget(); 186 187 void measureWidgetTree(int w); 188 void placeWidgetTree(int w); 189 190 void renderWidgetTree(int w); 191 192 public: Gui()193 Gui() : cursor(vec2f::zero()), defflash(0.0f) { } 194 195 bool loadColors(const std::string &filename); 196 197 /// 198 /// @brief Returns the Gui's colors. 199 /// getColors()200 GuiWidgetColors getColors() const 201 { 202 return colors; 203 } 204 setSSRender(PSSRender & render)205 void setSSRender(PSSRender &render) { ssRender = &render; } setFont(PTexture * tex)206 void setFont(PTexture *tex) { fonttex = tex; } 207 208 void tick(float delta); 209 210 void setCursorPos(float x, float y); 211 212 bool getClickAction(int &data1, int &data2); 213 bool getDefaultAction(int &data1, int &data2); 214 215 void doLayout(); 216 217 void render(); 218 clear()219 void clear() { widget.clear(); highlight = -1; defwidget = -1; } 220 221 int addContainer(int parent, float minwidth, float minheight, bool vert); 222 223 int addLabel(float x, float y, const std::string &text, uint32 flags, float fontsize, LabelStyle ls = LabelStyle::Regular); 224 225 int addGraphic(float x, float y, float width, float height, PTexture *tex, GraphicStyle gs = GraphicStyle::Image); 226 makeClickable(int w,int data1,int data2)227 int makeClickable(int w, int data1, int data2) { 228 widget[w].clickable = true; 229 widget[w].d1 = data1; 230 widget[w].d2 = data2; 231 return w; 232 } 233 makeUnclickable(int w)234 int makeUnclickable(int w) { 235 widget[w].clickable = false; 236 return w; 237 } 238 makeDefault(int w)239 void makeDefault(int w) { defwidget = w; } 240 }; 241 242 243