1 // Status Indicators 2 // 3 // Simple HUD window to show the status of things 4 // 5 // TODO change list 6 // Possibly use a coloured light or preferably an icon for 7 // the indicators rather than simple characters. 8 // 9 // Author bluap/pjbroad Jan 2014 10 // 11 12 #include <vector> 13 #include <string> 14 #include <iostream> 15 #include <cstring> 16 #include <sstream> 17 #include <utility> 18 19 #include "asc.h" 20 #include "chat.h" 21 #include "context_menu.h" 22 #include "counters.h" 23 #include "errors.h" 24 #include "font.h" 25 #include "elconfig.h" 26 #include "elwindows.h" 27 #include "gamewin.h" 28 #include "gl_init.h" 29 #include "hud.h" 30 #ifdef JSON_FILES 31 #include "json_io.h" 32 #endif 33 #include "sound.h" 34 #include "spells.h" 35 #include "text.h" 36 #include "translate.h" 37 38 using namespace eternal_lands; 39 40 namespace Indicators 41 { 42 // Constants used by the window. 43 // 44 class Vars 45 { 46 public: zoom(void)47 static float zoom(void) { return scale; } space(void)48 static int space(void) { return (int)(0.5 + scale * 5); } border(void)49 static int border(void) { return (int)(0.5 + scale * 2); } font_x(void)50 static float font_x(void) 51 { 52 return FontManager::get_instance() 53 .max_width_spacing(FontManager::Category::UI_FONT); 54 } font_y(void)55 static float font_y(void) 56 { 57 return FontManager::get_instance().line_height(FontManager::Category::UI_FONT); 58 } y_len(void)59 static int y_len(void) { return static_cast<int>(border() + zoom() * font_y() + 0.5); } set_scale(float new_scale)60 static void set_scale(float new_scale) { scale = new_scale; } 61 private: 62 static float scale; 63 }; 64 65 float Vars::scale = 1.0; 66 67 // A class to hold the state for an individual, basic indicator. 68 // Has a simple on / of state and no action. 69 // 70 class Basic_Indicator 71 { 72 public: 73 Basic_Indicator(const char *the_strings, int (*ctrl)(void), int (*unavailable)(void), int no); 74 virtual void do_draw(int x_pos); do_action(void) const75 virtual void do_action(void) const { do_alert1_sound(); } 76 virtual void get_tooltip(std::string & tooltip) const; get_context_menu_str(void) const77 virtual const std::string & get_context_menu_str(void) const { return context_menu_str; } get_active_var(void)78 virtual int *get_active_var(void) { return &is_active; } set_active(bool new_active)79 virtual void set_active(bool new_active) { is_active = (new_active) ?1 :0; } not_active(void) const80 virtual bool not_active(void) const { return (is_active==0); } set_over(void)81 virtual void set_over(void) { mouse_over = true; } get_width(void) const82 virtual int get_width(void) const { return indicator_text.size() * static_cast<int>(Vars::font_x() * Vars::zoom()); } ~Basic_Indicator(void)83 virtual ~Basic_Indicator(void) {} 84 protected: 85 std::string on_tooltip; 86 std::string off_tooltip; 87 std::string unavailable_tooltip; 88 int (*cntr_func)(void); 89 int (*unavailable_func)(void); 90 private: 91 std::string indicator_text; 92 std::string context_menu_str; 93 int is_active; 94 bool mouse_over; 95 }; 96 97 98 // A class to hold the state for an individual, basic indicator with a parsed action. 99 // Has a simple on/off state and an action string that is passed to the input parser. 100 // 101 class Parse_Action_Indicator: public Basic_Indicator 102 { 103 public: Parse_Action_Indicator(const char * the_strings,int (* ctrl)(void),int (* unavailable)(void),int no,const char * the_action)104 Parse_Action_Indicator(const char *the_strings, int (*ctrl)(void), int (*unavailable)(void), int no, const char *the_action) 105 : Basic_Indicator(the_strings, ctrl, unavailable, no), action(the_action) {} 106 virtual void do_action(void) const; ~Parse_Action_Indicator(void)107 virtual ~Parse_Action_Indicator(void) { } 108 private: 109 std::string action; 110 }; 111 112 113 // A class to hold the state for an individual, basic indicator with value and a click action function. 114 // Has a value rather than on/off state displayed in the tool-tip, the value is typically cleared by the action. 115 // 116 class Value_Indicator : public Basic_Indicator 117 { 118 public: Value_Indicator(const char * the_strings,int (* ctrl)(void),int (* unavailable)(void),int no,void (* action)(void))119 Value_Indicator(const char *the_strings, int (*ctrl)(void), int (*unavailable)(void), int no, void (*action)(void)) 120 : Basic_Indicator(the_strings, ctrl, unavailable, no), action_function(action) {} 121 virtual void do_action(void) const; 122 virtual void get_tooltip(std::string & tooltip) const; ~Value_Indicator(void)123 virtual ~Value_Indicator(void) { } 124 private: 125 void (*action_function)(void); 126 }; 127 128 129 // Class for the collection of indicators, and the window state and action methods. 130 // 131 class Indicators_Container 132 { 133 public: Indicators_Container(void)134 Indicators_Container(void) 135 : indicators_win(-1), cm_menu_id(CM_INIT_VALUE), 136 cm_relocatable(0), x_len(0), y_len(0), default_location(true), 137 option_settings(0), position_settings(0), have_settings(false), 138 background_on(0), border_on(0) {} 139 void init(void); 140 void destroy(void); show(void)141 void show(void) { if (indicators_win >= 0) show_window (indicators_win); } hide(void)142 void hide(void) { if (indicators_win >= 0) hide_window (indicators_win); } 143 void toggle(int show); 144 void draw(void); 145 void show_tooltip(window_info *win, int mx); 146 void click(int mx, Uint32 flags); 147 int cm_handler(window_info *win, int widget_id, int mx, int my, int option); set_settings(unsigned int opts,unsigned int pos)148 void set_settings(unsigned int opts, unsigned int pos) { option_settings = opts; position_settings = pos; have_settings = true;} 149 void get_settings(unsigned int *opts, unsigned int *pos) const; 150 #ifdef JSON_FILES 151 void read_settings(const char *dict_name); 152 void write_settings(const char *dict_name) const; 153 #endif ui_scale_handler(window_info * win)154 void ui_scale_handler(window_info *win) { x_len = 0; y_len = 0; Vars::set_scale(win->current_scale); } 155 int get_default_width(void); 156 private: 157 void set_win_flag(Uint32 flag, int state); set_background(bool on)158 void set_background(bool on) { background_on = on; set_win_flag(ELW_USE_BACKGROUND, background_on); } set_border(bool on)159 void set_border(bool on) { border_on = on; set_win_flag(ELW_USE_BORDER, border_on); } 160 std::vector<Basic_Indicator *> indicators; 161 int indicators_win; 162 size_t cm_menu_id; 163 int cm_relocatable; 164 int x_len; 165 int y_len; 166 bool default_location; 167 unsigned int option_settings; 168 unsigned int position_settings; 169 bool have_settings; 170 int background_on; 171 int border_on; 172 std::vector<Basic_Indicator *>::iterator get_over(int mx); 173 std::pair<int,int> get_default_location(void); 174 void change_width(int new_x_len); 175 enum { CMHI_RELOC=ELW_CM_MENU_LEN+1, CMHI_BACKGROUND, CMHI_BORDER, 176 CMHI_SPACE1, CMHI_RESET, CMHI_SPACE2, CMHI_INDBASE}; 177 }; 178 179 180 // Construct the indicator deriving the strings from the "||" separated string passed. 181 // Basic_Indicator(const char * the_strings,int (* ctrl)(void),int (* unavailable)(void),int no)182 Basic_Indicator::Basic_Indicator(const char *the_strings, int (*ctrl)(void), int (*unavailable)(void), int no) 183 : on_tooltip("Unset"), off_tooltip("Unset"), unavailable_tooltip("Unset"), cntr_func(ctrl), unavailable_func(unavailable), 184 indicator_text("*"), is_active(1), mouse_over(false) 185 { 186 if (the_strings) 187 { 188 std::string line_text(the_strings); 189 std::string::size_type from_index = 0; 190 std::string::size_type to_index = 0; 191 std::string delim = "||"; 192 std::string::size_type len = 0; 193 std::vector<std::string> fields; 194 while ((to_index = line_text.find(delim, from_index)) != std::string::npos) 195 { 196 if ((len = to_index-from_index) > 0) 197 fields.push_back(line_text.substr(from_index, len)); 198 from_index = to_index + delim.size(); 199 } 200 if ((len = line_text.size()-from_index) > 0) 201 fields.push_back(line_text.substr(from_index, len)); 202 if (fields.size() >= 4) 203 { 204 indicator_text = fields[0]; 205 on_tooltip = fields[1]; 206 off_tooltip = fields[2]; 207 context_menu_str = fields[3]; 208 if (fields.size() == 5) 209 unavailable_tooltip = fields[4]; 210 } 211 } 212 } 213 214 215 // Simply draw the single character, highlighted if the status is true. 216 // do_draw(int x_pos)217 void Basic_Indicator::do_draw(int x_pos) 218 { 219 if (mouse_over) 220 glColor3f(1.0f,1.0f,1.0f); 221 else if (unavailable_func && unavailable_func()) 222 glColor3f(gui_dull_color[0]/2, gui_dull_color[1]/2, gui_dull_color[2]/2); 223 else if (cntr_func && cntr_func()) 224 glColor3fv(gui_bright_color); 225 else 226 glColor3fv(gui_dull_color); 227 draw_string_zoomed(x_pos, Vars::border(), (const unsigned char*)indicator_text.c_str(), 1, Vars::zoom()); 228 mouse_over = false; 229 } 230 get_tooltip(std::string & tooltip) const231 void Basic_Indicator::get_tooltip(std::string & tooltip) const 232 { 233 if (unavailable_func && unavailable_func()) 234 tooltip = unavailable_tooltip; 235 else 236 tooltip = ((cntr_func && cntr_func()) ?on_tooltip : off_tooltip); 237 } 238 239 // If an action string is defined, execute using the standard command line parser. 240 // do_action(void) const241 void Parse_Action_Indicator::do_action(void) const 242 { 243 if (action.empty()) 244 { 245 Basic_Indicator::do_action(); 246 return; 247 } 248 size_t command_len = action.size() + 1; 249 do_click_sound(); 250 char temp[command_len]; 251 safe_strncpy(temp, action.c_str(), command_len); 252 parse_input(temp, strlen(temp)); 253 } 254 255 256 // Execute the click action, typically this clears the value. 257 // do_action(void) const258 void Value_Indicator::do_action(void) const 259 { 260 if (!action_function) 261 { 262 Basic_Indicator::do_action(); 263 return; 264 } 265 do_click_sound(); 266 action_function(); 267 } 268 269 270 // Show the tool-tip that explains the status and includes the current value if non-zero. 271 // get_tooltip(std::string & tooltip) const272 void Value_Indicator::get_tooltip(std::string & tooltip) const 273 { 274 if (unavailable_func && unavailable_func()) 275 { 276 tooltip = unavailable_tooltip; 277 return; 278 } 279 std::ostringstream ss(""); 280 int value = (cntr_func) ?cntr_func() :0; 281 if (value > 0) 282 ss << on_tooltip << " [" << value << "]"; 283 else 284 ss << off_tooltip; 285 tooltip = ss.str(); 286 } 287 288 289 // The indicators instance. 290 static Indicators_Container container; 291 292 293 // Window callback functions. 294 // display_indicators_handler(window_info * win)295 static int display_indicators_handler(window_info *win) { container.draw(); return 1; } mouseover_indicators_handler(window_info * win,int mx,int my)296 static int mouseover_indicators_handler(window_info *win, int mx, int my) { if (my>=0) container.show_tooltip(win, mx); return 0; } ui_scale_indicators_handler(window_info * win)297 static int ui_scale_indicators_handler(window_info *win) { container.ui_scale_handler(win); return 1; } click_indicators_handler(window_info * win,int mx,int my,Uint32 flags)298 static int click_indicators_handler(window_info *win, int mx, int my, Uint32 flags) { if (my>=0) container.click(mx, flags); return 1; } cm_indicators_handler(window_info * win,int widget_id,int mx,int my,int option)299 static int cm_indicators_handler(window_info *win, int widget_id, int mx, int my, int option) { return container.cm_handler(win, widget_id, mx, my, option); } 300 301 302 // Initialise the indicators, create or re-initialise the window. 303 // init(void)304 void Indicators_Container::init(void) 305 { 306 if (!FontManager::get_instance().is_initialized()) 307 return; 308 309 std::pair<int,int> loc = get_default_location(); 310 311 if (indicators.empty()) 312 { 313 indicators.reserve(6); 314 indicators.push_back(new Parse_Action_Indicator(day_indicator_str, today_is_special_day, 0, indicators.size(), "#day")); 315 indicators.push_back(new Basic_Indicator(harvest_indicator_str, now_harvesting, 0, indicators.size())); 316 indicators.push_back(new Basic_Indicator(poison_indicator_str, we_are_poisoned, 0, indicators.size())); 317 indicators.push_back(new Value_Indicator(messages_indicator_str, get_seen_pm_count, 0, indicators.size(), clear_seen_pm_count)); 318 indicators.push_back(new Parse_Action_Indicator(ranginglock_indicator_str, ranging_lock_is_on, 0, indicators.size(), "#keypress #K_RANGINGLOCK")); 319 indicators.push_back(new Parse_Action_Indicator(glowperk_indicator_str, glow_perk_is_active, glow_perk_is_unavailable, indicators.size(), "#glow")); 320 } 321 322 x_len = static_cast<int>(Vars::font_x() * indicators.size() * Vars::zoom() + 323 2 * Vars::border() + 2 * Vars::space() * indicators.size() + 0.5); 324 y_len = Vars::y_len(); 325 326 if (indicators_win < 0) 327 { 328 if (have_settings) 329 { 330 unsigned int flags = option_settings; 331 default_location = !((flags >> 24) & 1); 332 if (!default_location) 333 { 334 loc.first = static_cast<int>(position_settings & 0xFFFF); 335 loc.second = static_cast<int>((position_settings >> 16) & 0xFFFF); 336 } 337 std::vector<Basic_Indicator *>::iterator i; 338 for (i=indicators.begin(); i<indicators.end(); ++i) 339 { 340 (*i)->set_active(!static_cast<bool>(flags&1)); 341 flags >>= 1; 342 } 343 } 344 } 345 else if (!default_location) 346 { 347 loc.first = windows_list.window[indicators_win].cur_x; 348 loc.second = windows_list.window[indicators_win].cur_y; 349 } 350 351 if ((loc.first > (window_width - x_len)) || (loc.second > (window_height - y_len))) 352 loc = get_default_location(); 353 354 if (indicators_win < 0) 355 { 356 indicators_win = create_window("Indicators", -1, 0, loc.first, loc.second, x_len, y_len, ELW_USE_UISCALE|ELW_SHOW|ELW_ALPHA_BORDER|ELW_SWITCHABLE_OPAQUE); 357 if (indicators_win < 0 || indicators_win >= windows_list.num_windows) 358 { 359 LOG_ERROR("%s: Failed to create indicators window\n", __FILE__ ); 360 return; 361 } 362 set_window_handler(indicators_win, ELW_HANDLER_DISPLAY, (int (*)())&display_indicators_handler); 363 set_window_handler(indicators_win, ELW_HANDLER_MOUSEOVER, (int (*)())&mouseover_indicators_handler); 364 set_window_handler(indicators_win, ELW_HANDLER_CLICK, (int (*)())&click_indicators_handler); 365 set_window_handler(indicators_win, ELW_HANDLER_UI_SCALE, (int (*)())&ui_scale_indicators_handler); 366 ui_scale_indicators_handler(&windows_list.window[indicators_win]); 367 368 background_on = ((option_settings >> 25) & 1); 369 border_on = ((option_settings >> 26) & 1); 370 set_background(background_on); 371 set_border(border_on); 372 } 373 else 374 init_window(indicators_win, -1, 0, loc.first, loc.second, x_len, y_len); 375 376 if (!cm_valid(cm_menu_id)) 377 { 378 std::vector<Basic_Indicator *>::iterator i; 379 int j; 380 std::ostringstream cm_menu(""); 381 cm_menu << cm_indicators_str; 382 for (i=indicators.begin(); i<indicators.end(); ++i) 383 cm_menu << (*i)->get_context_menu_str() << std::endl; 384 cm_menu_id = cm_create(cm_title_menu_str, NULL); 385 cm_bool_line(cm_menu_id, 1, &windows_list.window[indicators_win].opaque, NULL); 386 cm_bool_line(cm_menu_id, 2, &windows_on_top, "windows_on_top"); 387 cm_add(cm_menu_id, cm_menu.str().c_str(), cm_indicators_handler); 388 cm_bool_line(cm_menu_id, CMHI_RELOC, &cm_relocatable, 0); 389 cm_bool_line(cm_menu_id, CMHI_BACKGROUND, &background_on, 0); 390 cm_bool_line(cm_menu_id, CMHI_BORDER, &border_on, 0); 391 for (i=indicators.begin(), j=0; i<indicators.end(); ++i, j++) 392 cm_bool_line(cm_menu_id, CMHI_INDBASE+j, (*i)->get_active_var(), 0); 393 cm_add_window(cm_menu_id, indicators_win); 394 } 395 } 396 397 398 // Delete the indicators and destroy the window. 399 // destroy(void)400 void Indicators_Container::destroy(void) 401 { 402 std::vector<Basic_Indicator *>::iterator i; 403 for (i=indicators.begin(); i<indicators.end(); ++i) 404 delete (*i); 405 indicators.clear(); 406 destroy_window(indicators_win); 407 indicators_win = -1; 408 if (cm_valid(cm_menu_id)) 409 cm_destroy(cm_menu_id); 410 } 411 412 413 // Called if the state changed in the configuration window. 414 // toggle(int show)415 void Indicators_Container::toggle(int show) 416 { 417 if (show) 418 { 419 if (indicators_win < 0) 420 init(); 421 else 422 show_window(indicators_win); 423 } 424 else 425 hide_window(indicators_win); 426 } 427 428 429 // Draw all the indicators. 430 // draw(void)431 void Indicators_Container::draw(void) 432 { 433 int pos_x = Vars::border(); 434 bool have_active = false; 435 std::vector<Basic_Indicator *>::iterator i = indicators.begin(); 436 for (;i<indicators.end(); ++i) 437 { 438 if ((*i)->not_active()) 439 continue; 440 pos_x += Vars::space(); 441 (*i)->do_draw(pos_x); 442 pos_x += (*i)->get_width() + Vars::space(); 443 have_active = true; 444 } 445 if (!have_active) 446 { 447 glColor3fv(gui_dull_color); 448 draw_string_zoomed(pos_x, Vars::border(), (const unsigned char *)no_indicators_str, 1, Vars::zoom()); 449 pos_x += static_cast<int>(strlen(no_indicators_str) * Vars::zoom() * Vars::font_x() + 0.5); 450 } 451 change_width(pos_x + Vars::border()); 452 } 453 454 455 // If different, resize the window and move if in the default location. 456 // change_width(int new_x_len)457 void Indicators_Container::change_width(int new_x_len) 458 { 459 if (new_x_len != x_len) 460 { 461 x_len = new_x_len; 462 y_len = Vars::y_len(); 463 resize_window (indicators_win, x_len, y_len); 464 if (default_location) 465 { 466 std::pair<int,int> loc = get_default_location(); 467 move_window(indicators_win, -1, 0, loc.first, loc.second); 468 } 469 } 470 } 471 472 473 // Return an iterator to the indicator under the mouse or .end() 474 // get_over(int mx)475 std::vector<Basic_Indicator *>::iterator Indicators_Container::get_over(int mx) 476 { 477 std::vector<Basic_Indicator *>::iterator i = indicators.begin(); 478 int pos_x = Vars::border(); 479 for (; i<indicators.end(); ++i) 480 { 481 if ((*i)->not_active()) 482 continue; 483 int width = (*i)->get_width() + 2 * Vars::space(); 484 if ((mx > pos_x) && (mx < (pos_x + width))) 485 { 486 (*i)->set_over(); 487 return i; 488 } 489 pos_x += width; 490 } 491 return indicators.end(); 492 } 493 494 495 // If the mouse is over an indicator, draw the tool-tip. 496 // show_tooltip(window_info * win,int mx)497 void Indicators_Container::show_tooltip(window_info *win, int mx) 498 { 499 std::vector<Basic_Indicator *>::iterator i = get_over(mx); 500 if (win && (i < indicators.end())) 501 { 502 eternal_lands::FontManager &fmgr = eternal_lands::FontManager::get_instance(); 503 std::string tooltip(""); 504 (*i)->get_tooltip(tooltip); 505 int width = fmgr.line_width(win->font_category, (const unsigned char*)tooltip.c_str(), 506 tooltip.length(), win->current_scale_small); 507 int x_offset = -(Vars::border() + width); 508 if ((win->cur_x + x_offset) < 0) 509 x_offset = win->len_x; 510 show_help(tooltip.c_str(), x_offset, Vars::border(), win->current_scale); 511 } 512 } 513 514 515 // If click an indicator, execute the action. 516 // click(int mx,Uint32 flags)517 void Indicators_Container::click(int mx, Uint32 flags) 518 { 519 if (flags&ELW_LEFT_MOUSE) 520 { 521 std::vector<Basic_Indicator *>::iterator i = get_over(mx); 522 if (i < indicators.end()) 523 (*i)->do_action(); 524 } 525 } 526 527 528 // Change a window property bit flag 529 // set_win_flag(Uint32 flag,int state)530 void Indicators_Container::set_win_flag(Uint32 flag, int state) 531 { 532 if ((indicators_win > -1) && (indicators_win < windows_list.num_windows)) 533 { 534 Uint32 *flags = &windows_list.window[indicators_win].flags; 535 if (state) 536 *flags |= flag; 537 else 538 *flags &= ~flag; 539 } 540 } 541 542 543 // The context menu callback function. 544 // cm_handler(window_info * win,int widget_id,int mx,int my,int option)545 int Indicators_Container::cm_handler(window_info *win, int widget_id, int mx, int my, int option) 546 { 547 size_t index = static_cast<size_t>(option - CMHI_INDBASE); 548 if (option < ELW_CM_MENU_LEN) 549 return cm_title_handler(win, widget_id, mx, my, option); 550 if (index < indicators.size()) 551 return 1; 552 switch (option) 553 { 554 case CMHI_RELOC: 555 if (win->flags & ELW_TITLE_BAR) 556 { 557 win->flags &= ~(ELW_TITLE_BAR|ELW_DRAGGABLE); 558 cm_relocatable = 0; 559 } 560 else 561 { 562 win->flags |= ELW_TITLE_BAR|ELW_DRAGGABLE; 563 cm_relocatable = 1; 564 default_location = false; 565 if (win->cur_y == 0) 566 move_window(win->window_id, -1, 0, win->cur_x, win->title_height); 567 } 568 if (win->cur_y == win->title_height) 569 move_window(win->window_id, -1, 0, win->cur_x, 0); 570 else if (win->cur_y == 0) 571 move_window(win->window_id, -1, 0, win->cur_x, win->title_height); 572 break; 573 case CMHI_BACKGROUND: set_background(background_on); break; 574 case CMHI_BORDER: set_border(border_on); break; 575 case CMHI_RESET: 576 { 577 std::pair<int,int> loc = get_default_location(); 578 move_window(indicators_win, -1, 0, loc.first, loc.second); 579 win->flags &= ~(ELW_TITLE_BAR|ELW_DRAGGABLE); 580 cm_relocatable = 0; 581 default_location = true; 582 set_background(false); 583 set_border(false); 584 break; 585 } 586 default: 587 return 0; 588 } 589 return 1; 590 } 591 592 593 // Get the width of the indicators window if enabled and in the default location, otherwise 0. 594 // get_default_width(void)595 int Indicators_Container::get_default_width(void) 596 { 597 if (!get_show_window(indicators_win) || !default_location || indicators_win < 0) 598 return 0; 599 return windows_list.window[indicators_win].len_x; 600 } 601 602 603 // Get the x,y location, nice and snug against the bottom and right border 604 // get_default_location(void)605 std::pair<int,int> Indicators_Container::get_default_location(void) 606 { 607 std::pair<int,int> loc; 608 loc.first = window_width - HUD_MARGIN_X - x_len; 609 loc.second = window_height - y_len; 610 return loc; 611 } 612 613 614 // Called when saving client settings 615 // get_settings(unsigned int * opts,unsigned int * pos) const616 void Indicators_Container::get_settings(unsigned int *opts, unsigned int *pos) const 617 { 618 unsigned int flags = 0; 619 unsigned int shift = 0; 620 unsigned int x = 0; 621 unsigned int y = 0; 622 623 if (indicators_win < 0) 624 { 625 *opts = option_settings; 626 *pos = position_settings; 627 return; 628 } 629 630 std::vector<Basic_Indicator *>::const_iterator i; 631 for (i=indicators.begin(); i<indicators.end(); ++i, shift++) 632 flags |= (((*i)->not_active()) ?1 :0) << shift; 633 634 if (!default_location) 635 flags |= 1 << 24; 636 flags |= background_on << 25; 637 flags |= border_on << 26; 638 *opts = flags; 639 640 x = static_cast<unsigned int>(windows_list.window[indicators_win].cur_x); 641 y = static_cast<unsigned int>(windows_list.window[indicators_win].cur_y); 642 *pos = x | (y<<16); 643 } 644 645 646 #ifdef JSON_FILES 647 // Read the options from the client state file 648 // read_settings(const char * dict_name)649 void Indicators_Container::read_settings(const char *dict_name) 650 { 651 int pos_x = json_cstate_get_int(dict_name, "pos_x", 0); 652 int pos_y = json_cstate_get_int(dict_name, "pos_y", 0); 653 position_settings = (pos_x & 0xFFFF) | ((pos_y & 0xFFFF) << 16); 654 655 option_settings = json_cstate_get_unsigned_int(dict_name, "disabled_flags", 0); 656 option_settings |= json_cstate_get_bool(dict_name, "relocated", 0) << 24; 657 option_settings |= json_cstate_get_bool(dict_name, "background_on", 0) << 25; 658 option_settings |= json_cstate_get_bool(dict_name, "border_on", 0) << 26; 659 have_settings = true; 660 } 661 662 663 // Write the options from the client state file 664 // write_settings(const char * dict_name) const665 void Indicators_Container::write_settings(const char *dict_name) const 666 { 667 if (indicators_win < 0) 668 { 669 json_cstate_set_int(dict_name, "pos_x", position_settings & 0xFFFF); 670 json_cstate_set_int(dict_name, "pos_y", (position_settings >> 16 ) & 0xFFFF); 671 json_cstate_set_unsigned_int(dict_name, "disabled_flags", option_settings & 0x00FFFFFF); 672 json_cstate_set_bool(dict_name, "relocated", (option_settings >> 24) & 1); 673 json_cstate_set_bool(dict_name, "background_on", (option_settings >> 25) & 1); 674 json_cstate_set_bool(dict_name, "border_on", (option_settings >> 26) & 1); 675 return; 676 } 677 678 unsigned int disabled_flags = 0, shift = 0; 679 std::vector<Basic_Indicator *>::const_iterator i; 680 for (i=indicators.begin(); i<indicators.end(); ++i, shift++) 681 disabled_flags |= (((*i)->not_active()) ?1 :0) << shift; 682 json_cstate_set_unsigned_int(dict_name, "disabled_flags", disabled_flags); 683 684 json_cstate_set_unsigned_int(dict_name, "pos_x", static_cast<unsigned int>(windows_list.window[indicators_win].cur_x)); 685 json_cstate_set_unsigned_int(dict_name, "pos_y", static_cast<unsigned int>(windows_list.window[indicators_win].cur_y)); 686 json_cstate_set_bool(dict_name, "relocated", (default_location) ?0: 1); 687 json_cstate_set_bool(dict_name, "background_on", background_on); 688 json_cstate_set_bool(dict_name, "border_on", border_on); 689 } 690 #endif 691 692 } // end namespace 693 694 695 // Variables and functions accessible from rest of client 696 // 697 extern "C" 698 { 699 int show_hud_indicators = 1; init_hud_indicators(void)700 void init_hud_indicators(void) { if (show_hud_indicators) Indicators::container.init(); } destroy_hud_indicators(void)701 void destroy_hud_indicators(void) { Indicators::container.destroy(); } show_hud_indicators_window(void)702 void show_hud_indicators_window(void) { if (show_hud_indicators) Indicators::container.show(); } hide_hud_indicators_window(void)703 void hide_hud_indicators_window(void) { Indicators::container.hide(); } toggle_hud_indicators_window(int * show)704 void toggle_hud_indicators_window(int *show) { *show = !*show; Indicators::container.toggle(*show); } set_settings_hud_indicators(unsigned int opts,unsigned int pos)705 void set_settings_hud_indicators(unsigned int opts, unsigned int pos) { Indicators::container.set_settings(opts, pos); } get_settings_hud_indicators(unsigned int * opts,unsigned int * pos)706 void get_settings_hud_indicators(unsigned int *opts, unsigned int *pos) { Indicators::container.get_settings(opts, pos); } 707 #ifdef JSON_FILES read_settings_hud_indicators(const char * dict_name)708 void read_settings_hud_indicators(const char *dict_name) { Indicators::container.read_settings(dict_name); } write_settings_hud_indicators(const char * dict_name)709 void write_settings_hud_indicators(const char *dict_name) { Indicators::container.write_settings(dict_name); } 710 #endif get_hud_indicators_default_width(void)711 int get_hud_indicators_default_width(void) { if (show_hud_indicators) return Indicators::container.get_default_width(); else return 0; } 712 } 713