00001
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 == 0x0D) {
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
00104 SetDParam(0, c->money);
00105 DrawStringCentered(this->widget[SBW_RIGHT].left + 70, 1, STR_0004, TC_FROMSTRING);
00106 }
00107
00108
00109 if (this->saving) {
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
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
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
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;
00146 this->reminder_timeout = REMINDER_STOP;
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) {
00165 this->ticker_scroll -= COUNTER_STEP;
00166 this->InvalidateWidget(SBW_MIDDLE);
00167 }
00168
00169 if (this->reminder_timeout > REMINDER_STOP) {
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 }