statusbar_gui.cpp

Go to the documentation of this file.
00001 /* $Id: statusbar_gui.cpp 15723 2009-03-15 15:12:06Z rubidium $ */
00002 
00005 #include "stdafx.h"
00006 #include "openttd.h"
00007 #include "settings_type.h"
00008 #include "date_func.h"
00009 #include "gfx_func.h"
00010 #include "news_func.h"
00011 #include "company_func.h"
00012 #include "string_func.h"
00013 #include "strings_func.h"
00014 #include "company_base.h"
00015 #include "tilehighlight_func.h"
00016 #include "news_gui.h"
00017 #include "company_gui.h"
00018 #include "window_gui.h"
00019 #include "variables.h"
00020 #include "window_func.h"
00021 #include "statusbar_gui.h"
00022 
00023 #include "table/strings.h"
00024 #include "table/sprites.h"
00025 
00026 static bool DrawScrollingStatusText(const NewsItem *ni, int pos, int width)
00027 {
00028   CopyInDParam(0, ni->params, lengthof(ni->params));
00029   StringID str = ni->string_id;
00030 
00031   char buf[512];
00032   GetString(buf, str, lastof(buf));
00033   const char *s = buf;
00034 
00035   char buffer[256];
00036   char *d = buffer;
00037   const char *last = lastof(buffer);
00038 
00039   for (;;) {
00040     WChar c = Utf8Consume(&s);
00041     if (c == 0) {
00042       break;
00043     } else if (c == '\n') {
00044       if (d + 4 >= last) break;
00045       d[0] = d[1] = d[2] = d[3] = ' ';
00046       d += 4;
00047     } else if (IsPrintable(c)) {
00048       if (d + Utf8CharLen(c) >= last) break;
00049       d += Utf8Encode(d, c);
00050     }
00051   }
00052   *d = '\0';
00053 
00054   DrawPixelInfo tmp_dpi;
00055   if (!FillDrawPixelInfo(&tmp_dpi, 141, 1, width, 11)) return true;
00056 
00057   DrawPixelInfo *old_dpi = _cur_dpi;
00058   _cur_dpi = &tmp_dpi;
00059 
00060   int x = DoDrawString(buffer, pos, 0, TC_LIGHT_BLUE);
00061   _cur_dpi = old_dpi;
00062 
00063   return x > 0;
00064 }
00065 
00066 struct StatusBarWindow : Window {
00067   bool saving;
00068   int ticker_scroll;
00069   int reminder_timeout;
00070 
00071   enum {
00072     TICKER_START   =   360, 
00073     TICKER_STOP    = -1280, 
00074     REMINDER_START =    91, 
00075     REMINDER_STOP  =     0, 
00076     COUNTER_STEP   =     2, 
00077   };
00078 
00079   enum StatusbarWidget {
00080     SBW_LEFT,   
00081     SBW_MIDDLE, 
00082     SBW_RIGHT,  
00083   };
00084 
00085   StatusBarWindow(const WindowDesc *desc) : Window(desc)
00086   {
00087     CLRBITS(this->flags4, WF_WHITE_BORDER_MASK);
00088     this->ticker_scroll    =   TICKER_STOP;
00089     this->reminder_timeout = REMINDER_STOP;
00090 
00091     this->FindWindowPlacementAndResize(desc);
00092   }
00093 
00094   virtual void OnPaint()
00095   {
00096     const Company *c = (_local_company == COMPANY_SPECTATOR) ? NULL : GetCompany(_local_company);
00097 
00098     this->DrawWidgets();
00099     SetDParam(0, _date);
00100     DrawStringCentered(70, 1, (_pause_game || _settings_client.gui.status_long_date) ? STR_00AF : STR_00AE, TC_FROMSTRING);
00101 
00102     if (c != NULL) {
00103       /* Draw company money */
00104       SetDParam(0, c->money);
00105       DrawStringCentered(this->widget[SBW_RIGHT].left + 70, 1, STR_0004, TC_FROMSTRING);
00106     }
00107 
00108     /* Draw status bar */
00109     if (this->saving) { // true when saving is active
00110       DrawStringCenteredTruncated(this->widget[SBW_MIDDLE].left + 1, this->widget[SBW_MIDDLE].right - 1, 1, STR_SAVING_GAME, TC_FROMSTRING);
00111     } else if (_do_autosave) {
00112       DrawStringCenteredTruncated(this->widget[SBW_MIDDLE].left + 1, this->widget[SBW_MIDDLE].right - 1, 1, STR_032F_AUTOSAVE, TC_FROMSTRING);
00113     } else if (_pause_game) {
00114       DrawStringCenteredTruncated(this->widget[SBW_MIDDLE].left + 1, this->widget[SBW_MIDDLE].right - 1, 1, STR_0319_PAUSED, TC_FROMSTRING);
00115     } else if (this->ticker_scroll > TICKER_STOP && FindWindowById(WC_NEWS_WINDOW, 0) == NULL && _statusbar_news_item.string_id != 0) {
00116       /* Draw the scrolling news text */
00117       if (!DrawScrollingStatusText(&_statusbar_news_item, this->ticker_scroll, this->widget[SBW_MIDDLE].right - this->widget[SBW_MIDDLE].left - 2)) {
00118         this->ticker_scroll = TICKER_STOP;
00119         if (c != NULL) {
00120           /* This is the default text */
00121           SetDParam(0, c->index);
00122           DrawStringCenteredTruncated(this->widget[SBW_MIDDLE].left + 1, this->widget[SBW_MIDDLE].right - 1, 1, STR_02BA, TC_FROMSTRING);
00123         }
00124       }
00125     } else {
00126       if (c != NULL) {
00127         /* This is the default text */
00128         SetDParam(0, c->index);
00129         DrawStringCenteredTruncated(this->widget[SBW_MIDDLE].left + 1, this->widget[SBW_MIDDLE].right - 1, 1, STR_02BA, TC_FROMSTRING);
00130       }
00131     }
00132 
00133     if (this->reminder_timeout > 0) DrawSprite(SPR_BLOT, PALETTE_TO_RED, this->widget[SBW_MIDDLE].right - 11, 2);
00134   }
00135 
00136   virtual void OnInvalidateData(int data)
00137   {
00138     switch (data) {
00139       default: NOT_REACHED();
00140       case SBI_SAVELOAD_START:  this->saving = true;  break;
00141       case SBI_SAVELOAD_FINISH: this->saving = false; break;
00142       case SBI_SHOW_TICKER:     this->ticker_scroll    =   TICKER_START; break;
00143       case SBI_SHOW_REMINDER:   this->reminder_timeout = REMINDER_START; break;
00144       case SBI_NEWS_DELETED:
00145         this->ticker_scroll    =   TICKER_STOP; // reset ticker ...
00146         this->reminder_timeout = REMINDER_STOP; // ... and reminder
00147         break;
00148     }
00149   }
00150 
00151   virtual void OnClick(Point pt, int widget)
00152   {
00153     switch (widget) {
00154       case SBW_MIDDLE: ShowLastNewsMessage(); break;
00155       case SBW_RIGHT:  if (_local_company != COMPANY_SPECTATOR) ShowCompanyFinances(_local_company); break;
00156       default: ResetObjectToPlace();
00157     }
00158   }
00159 
00160   virtual void OnTick()
00161   {
00162     if (_pause_game) return;
00163 
00164     if (this->ticker_scroll > TICKER_STOP) { // Scrolling text
00165       this->ticker_scroll -= COUNTER_STEP;
00166       this->InvalidateWidget(SBW_MIDDLE);
00167     }
00168 
00169     if (this->reminder_timeout > REMINDER_STOP) { // Red blot to show there are new unread newsmessages
00170       this->reminder_timeout -= COUNTER_STEP;
00171     } else if (this->reminder_timeout < REMINDER_STOP) {
00172       this->reminder_timeout = REMINDER_STOP;
00173       this->InvalidateWidget(SBW_MIDDLE);
00174     }
00175   }
00176 };
00177 
00178 static const Widget _main_status_widgets[] = {
00179 {      WWT_PANEL,   RESIZE_NONE,   COLOUR_GREY,     0,   139,     0,    11, 0x0, STR_NULL},
00180 {    WWT_PUSHBTN,   RESIZE_RIGHT,  COLOUR_GREY,   140,   179,     0,    11, 0x0, STR_02B7_SHOW_LAST_MESSAGE_OR_NEWS},
00181 {    WWT_PUSHBTN,   RESIZE_LR,     COLOUR_GREY,   180,   319,     0,    11, 0x0, STR_NULL},
00182 {   WIDGETS_END},
00183 };
00184 
00185 static WindowDesc _main_status_desc(
00186   WDP_CENTER, 0, 320, 12, 640, 12,
00187   WC_STATUS_BAR, WC_NONE,
00188   WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_NO_FOCUS,
00189   _main_status_widgets
00190 );
00191 
00195 bool IsNewsTickerShown()
00196 {
00197   const StatusBarWindow *w = dynamic_cast<StatusBarWindow*>(FindWindowById(WC_STATUS_BAR, 0));
00198   return w != NULL && w->ticker_scroll > StatusBarWindow::TICKER_STOP;
00199 }
00200 
00201 void ShowStatusBar()
00202 {
00203   _main_status_desc.top = _screen.height - 12;
00204   new StatusBarWindow(&_main_status_desc);
00205 }

Generated on Thu Oct 1 11:03:17 2009 for OpenTTD by  doxygen 1.5.6