/** * Finish a paste process. * @return Total cost. */ static CommandCost FinalizePasting() { /* Set error string parameters */ CopyInDParam(0, _current_pasting->err_params, lengthof(_current_pasting->err_params)); /* Set error summary message (see COPY_PASTE_ERR_SUMMARY_PARAM for details). */ SetDParam(COPY_PASTE_ERR_SUMMARY_PARAM, _current_pasting->err_summary); /* Store the error tile so the GUI (CcPaste) can highlight it. */ _paste_err_tile = _current_pasting->err_tile; CommandCost ret; if (_current_pasting->had_success) { /* Return overal cost of the operation */ ret = CommandCost(EXPENSES_CONSTRUCTION, _current_pasting->overal_cost); /* Here we are about to return a success. However, there could occured some meaningful * errors (those except "already built", "already leveled" etc.) and we should inform * the user that not everything went right. Show the message now. */ if ((_current_pasting->dc_flags & DC_EXEC) && IsLocalCompany() && GetPasteErrorImportance(_current_pasting->err_message) > GetPasteErrorImportance(STR_ERROR_NOTHING_TO_DO)) { ShowErrorMessage(_current_pasting->err_summary, _current_pasting->err_message, WL_INFO); } else { /* If we are not showing error message then clear the error tile to prevent GUI * (CcPaste) from higlighting it. */ _paste_err_tile = INVALID_TILE; } } else { /* Return an error if we didn't have any success. */ ret = CommandCost(_current_pasting->err_message); } /* cleanup */ delete _current_pasting; _current_pasting = NULL; return ret; }
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) { switch (widget) { case WID_EM_MESSAGE: { CopyInDParam(0, this->decode_params, lengthof(this->decode_params)); if (this->textref_stack_size > 0) StartTextRefStackUsage(this->textref_stack_grffile, this->textref_stack_size, this->textref_stack); int text_width = max(0, (int)size->width - WD_FRAMETEXT_LEFT - WD_FRAMETEXT_RIGHT); this->height_summary = GetStringHeight(this->summary_msg, text_width); this->height_detailed = (this->detailed_msg == INVALID_STRING_ID) ? 0 : GetStringHeight(this->detailed_msg, text_width); if (this->textref_stack_size > 0) StopTextRefStackUsage(); uint panel_height = WD_FRAMERECT_TOP + this->height_summary + WD_FRAMERECT_BOTTOM; if (this->detailed_msg != INVALID_STRING_ID) panel_height += this->height_detailed + WD_PAR_VSEP_WIDE; size->height = max(size->height, panel_height); break; } case WID_EM_FACE: { Dimension face_size = GetSpriteSize(SPR_GRADIENT); size->width = max(size->width, face_size.width); size->height = max(size->height, face_size.height); break; } } }
/** * Draw an unformatted news message truncated to a maximum length. If * length exceeds maximum length it will be postfixed by '...' * @param left the left most location for the string * @param right the right most location for the string * @param y position of the string * @param colour the colour the string will be shown in * @param *ni NewsItem being printed * @param maxw maximum width of string in pixels */ static void DrawNewsString(uint left, uint right, int y, TextColour colour, const NewsItem *ni) { char buffer[512], buffer2[512]; StringID str; CopyInDParam(0, ni->params, lengthof(ni->params)); str = ni->string_id; GetString(buffer, str, lastof(buffer)); /* Copy the just gotten string to another buffer to remove any formatting * from it such as big fonts, etc. */ const char *ptr = buffer; char *dest = buffer2; WChar c_last = '\0'; for (;;) { WChar c = Utf8Consume(&ptr); if (c == 0) break; /* Make a space from a newline, but ignore multiple newlines */ if (c == '\n' && c_last != '\n') { dest[0] = ' '; dest++; } else if (c == '\r') { dest[0] = dest[1] = dest[2] = dest[3] = ' '; dest += 4; } else if (IsPrintable(c)) { dest += Utf8Encode(dest, c); } c_last = c; } *dest = '\0'; /* Truncate and show string; postfixed by '...' if necessary */ DrawString(left, right, y, buffer2, colour); }
virtual void DrawWidget(const Rect &r, int widget) const { switch (widget) { case WID_N_CAPTION: DrawCaption(r, COLOUR_LIGHT_BLUE, this->owner, STR_NEWS_MESSAGE_CAPTION); break; case WID_N_PANEL: this->DrawNewsBorder(r); break; case WID_N_MESSAGE: CopyInDParam(0, this->ni->params, lengthof(this->ni->params)); DrawStringMultiLine(r.left, r.right, r.top, r.bottom, this->ni->string_id, TC_FROMSTRING, SA_CENTER); break; case WID_N_MGR_FACE: { const CompanyNewsInformation *cni = (const CompanyNewsInformation*)this->ni->free_data; DrawCompanyManagerFace(cni->face, cni->colour, r.left, r.top); GfxFillRect(r.left, r.top, r.right, r.bottom, PALETTE_NEWSPAPER, FILLRECT_RECOLOUR); break; } case WID_N_MGR_NAME: { const CompanyNewsInformation *cni = (const CompanyNewsInformation*)this->ni->free_data; SetDParamStr(0, cni->president_name); DrawStringMultiLine(r.left, r.right, r.top, r.bottom, STR_JUST_RAW_STRING, TC_FROMSTRING, SA_CENTER); break; } case WID_N_COMPANY_MSG: DrawStringMultiLine(r.left, r.right, r.top, r.bottom, this->GetCompanyMessageString(), TC_FROMSTRING, SA_CENTER); break; case WID_N_VEH_BKGND: GfxFillRect(r.left, r.top, r.right, r.bottom, PC_GREY); break; case WID_N_VEH_NAME: case WID_N_VEH_TITLE: DrawStringMultiLine(r.left, r.right, r.top, r.bottom, this->GetNewVehicleMessageString(widget), TC_FROMSTRING, SA_CENTER); break; case WID_N_VEH_SPR: { assert(this->ni->reftype1 == NR_ENGINE); EngineID engine = this->ni->ref1; DrawVehicleEngine(r.left, r.right, (r.left + r.right) / 2, (r.top + r.bottom) / 2, engine, GetEnginePalette(engine, _local_company), EIT_PREVIEW); GfxFillRect(r.left, r.top, r.right, r.bottom, PALETTE_NEWSPAPER, FILLRECT_RECOLOUR); break; } case WID_N_VEH_INFO: { assert(this->ni->reftype1 == NR_ENGINE); EngineID engine = this->ni->ref1; DrawStringMultiLine(r.left, r.right, r.top, r.bottom, GetEngineInfoString(engine), TC_FROMSTRING, SA_CENTER); break; } } }
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) { StringID str = STR_NULL; switch (widget) { case WID_N_CAPTION: { /* Caption is not a real caption (so that the window cannot be moved) * thus it doesn't get the default sizing of a caption. */ Dimension d2 = GetStringBoundingBox(STR_NEWS_MESSAGE_CAPTION); d2.height += WD_CAPTIONTEXT_TOP + WD_CAPTIONTEXT_BOTTOM; *size = maxdim(*size, d2); return; } case WID_N_MGR_FACE: *size = maxdim(*size, GetSpriteSize(SPR_GRADIENT)); break; case WID_N_MESSAGE: CopyInDParam(0, this->ni->params, lengthof(this->ni->params)); str = this->ni->string_id; break; case WID_N_COMPANY_MSG: str = this->GetCompanyMessageString(); break; case WID_N_VEH_NAME: case WID_N_VEH_TITLE: str = this->GetNewVehicleMessageString(widget); break; case WID_N_VEH_INFO: { assert(this->ni->reftype1 == NR_ENGINE); EngineID engine = this->ni->ref1; str = GetEngineInfoString(engine); break; } default: return; // Do nothing } /* Update minimal size with length of the multi-line string. */ Dimension d = *size; d.width = (d.width >= padding.width) ? d.width - padding.width : 0; d.height = (d.height >= padding.height) ? d.height - padding.height : 0; d = GetStringMultiLineBoundingBox(str, d); d.width += padding.width; d.height += padding.height; *size = maxdim(*size, d); }
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) { if (widget != WID_EM_MESSAGE) return; CopyInDParam(0, this->decode_params, lengthof(this->decode_params)); if (this->textref_stack_size > 0) StartTextRefStackUsage(this->textref_stack_size, this->textref_stack); int text_width = max(0, (int)size->width - WD_FRAMETEXT_LEFT - WD_FRAMETEXT_RIGHT); this->height_summary = GetStringHeight(this->summary_msg, text_width); this->height_detailed = (this->detailed_msg == INVALID_STRING_ID) ? 0 : GetStringHeight(this->detailed_msg, text_width); if (this->textref_stack_size > 0) StopTextRefStackUsage(); uint panel_height = WD_FRAMERECT_TOP + this->height_summary + WD_FRAMERECT_BOTTOM; if (this->detailed_msg != INVALID_STRING_ID) panel_height += this->height_detailed + WD_PAR_VSEP_WIDE; size->height = max(size->height, panel_height); }
static bool DrawScrollingStatusText(const NewsItem *ni, int scroll_pos, int left, int right, int top, int bottom) { CopyInDParam(0, ni->params, lengthof(ni->params)); StringID str = ni->string_id; char buf[512]; GetString(buf, str, lastof(buf)); const char *s = buf; char buffer[256]; char *d = buffer; const char *last = lastof(buffer); for (;;) { WChar c = Utf8Consume(&s); if (c == 0) { break; } else if (c == '\n') { if (d + 4 >= last) break; d[0] = d[1] = d[2] = d[3] = ' '; d += 4; } else if (IsPrintable(c)) { if (d + Utf8CharLen(c) >= last) break; d += Utf8Encode(d, c); } } *d = '\0'; DrawPixelInfo tmp_dpi; if (!FillDrawPixelInfo(&tmp_dpi, left, top, right - left, bottom)) return true; int width = GetStringBoundingBox(buffer).width; int pos = (_current_text_dir == TD_RTL) ? (scroll_pos - width) : (right - scroll_pos - left); DrawPixelInfo *old_dpi = _cur_dpi; _cur_dpi = &tmp_dpi; DrawString(pos, INT16_MAX, 0, buffer, TC_LIGHT_BLUE, SA_LEFT | SA_FORCE); _cur_dpi = old_dpi; return (_current_text_dir == TD_RTL) ? (pos < right - left) : (pos + width > 0); }
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) { StringID str = STR_NULL; switch (widget) { case WID_N_MESSAGE: size->width = GetMinSizing(NWST_WINDOW_LENGTH, size->width); CopyInDParam(0, this->ni->params, lengthof(this->ni->params)); str = this->ni->string_id; break; case WID_N_COMPANY_MSG: str = this->GetCompanyMessageString(); break; case WID_N_VEH_NAME: case WID_N_VEH_TITLE: str = this->GetNewVehicleMessageString(widget); break; case WID_N_VEH_INFO: { assert(this->ni->reftype1 == NR_ENGINE); EngineID engine = this->ni->ref1; str = GetEngineInfoString(engine); break; } default: return; // Do nothing } /* Update minimal size with length of the multi-line string. */ Dimension d = *size; d.width = (d.width >= padding.width) ? d.width - padding.width : 0; d.height = (d.height >= padding.height) ? d.height - padding.height : 0; d = GetStringMultiLineBoundingBox(str, d); d.width += padding.width; d.height += padding.height; *size = maxdim(*size, d); }
StringID GetCompanyMessageString() const { /* Company news with a face have a separate headline, so the normal message is shifted by two params */ CopyInDParam(0, this->ni->params + 2, lengthof(this->ni->params) - 2); return this->ni->params[1]; }