OpenTTD
network_content_gui.cpp
Go to the documentation of this file.
1 /* $Id: network_content_gui.cpp 27893 2017-08-13 18:38:42Z frosch $ */
2 
3 /*
4  * This file is part of OpenTTD.
5  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
6  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
7  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
8  */
9 
12 #if defined(ENABLE_NETWORK)
13 #include "../stdafx.h"
14 #include "../strings_func.h"
15 #include "../gfx_func.h"
16 #include "../window_func.h"
17 #include "../error.h"
18 #include "../ai/ai.hpp"
19 #include "../game/game.hpp"
20 #include "../base_media_base.h"
21 #include "../sortlist_type.h"
22 #include "../stringfilter_type.h"
23 #include "../querystring_gui.h"
24 #include "../core/geometry_func.hpp"
25 #include "../textfile_gui.h"
26 #include "network_content_gui.h"
27 
28 
29 #include "table/strings.h"
30 #include "../table/sprites.h"
31 
32 #include <bitset>
33 
34 #include "../safeguards.h"
35 
36 
38 static bool _accepted_external_search = false;
39 
40 
43  const ContentInfo *ci;
44 
46  {
47  const char *textfile = this->ci->GetTextfile(file_type);
48  this->LoadTextfile(textfile, GetContentInfoSubDir(this->ci->type));
49  }
50 
51  StringID GetTypeString() const
52  {
53  switch (this->ci->type) {
54  case CONTENT_TYPE_NEWGRF: return STR_CONTENT_TYPE_NEWGRF;
55  case CONTENT_TYPE_BASE_GRAPHICS: return STR_CONTENT_TYPE_BASE_GRAPHICS;
56  case CONTENT_TYPE_BASE_SOUNDS: return STR_CONTENT_TYPE_BASE_SOUNDS;
57  case CONTENT_TYPE_BASE_MUSIC: return STR_CONTENT_TYPE_BASE_MUSIC;
58  case CONTENT_TYPE_AI: return STR_CONTENT_TYPE_AI;
59  case CONTENT_TYPE_AI_LIBRARY: return STR_CONTENT_TYPE_AI_LIBRARY;
60  case CONTENT_TYPE_GAME: return STR_CONTENT_TYPE_GAME_SCRIPT;
61  case CONTENT_TYPE_GAME_LIBRARY: return STR_CONTENT_TYPE_GS_LIBRARY;
62  case CONTENT_TYPE_SCENARIO: return STR_CONTENT_TYPE_SCENARIO;
63  case CONTENT_TYPE_HEIGHTMAP: return STR_CONTENT_TYPE_HEIGHTMAP;
64  default: NOT_REACHED();
65  }
66  }
67 
68  /* virtual */ void SetStringParameters(int widget) const
69  {
70  if (widget == WID_TF_CAPTION) {
71  SetDParam(0, this->GetTypeString());
72  SetDParamStr(1, this->ci->name);
73  }
74  }
75 };
76 
77 void ShowContentTextfileWindow(TextfileType file_type, const ContentInfo *ci)
78 {
81 }
82 
85  NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_CONTENT_DOWNLOAD_TITLE, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
86  NWidget(WWT_PANEL, COLOUR_GREY, WID_NCDS_BACKGROUND),
90  NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NCDS_CANCELOK), SetMinimalSize(101, 12), SetDataTip(STR_BUTTON_CANCEL, STR_NULL),
91  NWidget(NWID_SPACER), SetFill(1, 0),
92  EndContainer(),
94  EndContainer(),
95 };
96 
99  WDP_CENTER, NULL, 0, 0,
101  WDF_MODAL,
102  _nested_network_content_download_status_window_widgets, lengthof(_nested_network_content_download_status_window_widgets)
103 );
104 
106  Window(desc), cur_id(UINT32_MAX)
107 {
110 
112 }
113 
115 {
117 }
118 
119 /* virtual */ void BaseNetworkContentDownloadStatusWindow::DrawWidget(const Rect &r, int widget) const
120 {
121  if (widget != WID_NCDS_BACKGROUND) return;
122 
123  /* Draw nice progress bar :) */
124  DrawFrameRect(r.left + 20, r.top + 4, r.left + 20 + (int)((this->width - 40LL) * this->downloaded_bytes / this->total_bytes), r.top + 14, COLOUR_MAUVE, FR_NONE);
125 
126  int y = r.top + 20;
127  SetDParam(0, this->downloaded_bytes);
128  SetDParam(1, this->total_bytes);
129  SetDParam(2, this->downloaded_bytes * 100LL / this->total_bytes);
130  DrawString(r.left + 2, r.right - 2, y, STR_CONTENT_DOWNLOAD_PROGRESS_SIZE, TC_FROMSTRING, SA_HOR_CENTER);
131 
132  StringID str;
133  if (this->downloaded_bytes == this->total_bytes) {
134  str = STR_CONTENT_DOWNLOAD_COMPLETE;
135  } else if (!StrEmpty(this->name)) {
136  SetDParamStr(0, this->name);
137  SetDParam(1, this->downloaded_files);
138  SetDParam(2, this->total_files);
139  str = STR_CONTENT_DOWNLOAD_FILE;
140  } else {
141  str = STR_CONTENT_DOWNLOAD_INITIALISE;
142  }
143 
144  y += FONT_HEIGHT_NORMAL + 5;
145  DrawStringMultiLine(r.left + 2, r.right - 2, y, y + FONT_HEIGHT_NORMAL * 2, str, TC_FROMSTRING, SA_CENTER);
146 }
147 
149 {
150  if (ci->id != this->cur_id) {
151  strecpy(this->name, ci->filename, lastof(this->name));
152  this->cur_id = ci->id;
153  this->downloaded_files++;
154  }
155 
156  this->downloaded_bytes += bytes;
157  this->SetDirty();
158 }
159 
160 
163 private:
165 
166 public:
171  NetworkContentDownloadStatusWindow() : BaseNetworkContentDownloadStatusWindow(&_network_content_download_status_window_desc)
172  {
174  }
175 
178  {
180  for (ContentType *iter = this->receivedTypes.Begin(); iter != this->receivedTypes.End(); iter++) {
181  switch (*iter) {
182  case CONTENT_TYPE_AI:
184  /* AI::Rescan calls the scanner. */
185  break;
186  case CONTENT_TYPE_GAME:
188  /* Game::Rescan calls the scanner. */
189  break;
190 
194  mode |= TarScanner::BASESET;
195  break;
196 
197  case CONTENT_TYPE_NEWGRF:
198  /* ScanNewGRFFiles calls the scanner. */
199  break;
200 
203  mode |= TarScanner::SCENARIO;
204  break;
205 
206  default:
207  break;
208  }
209  }
210 
211  TarScanner::DoScan(mode);
212 
213  /* Tell all the backends about what we've downloaded */
214  for (ContentType *iter = this->receivedTypes.Begin(); iter != this->receivedTypes.End(); iter++) {
215  switch (*iter) {
216  case CONTENT_TYPE_AI:
218  AI::Rescan();
219  break;
220 
221  case CONTENT_TYPE_GAME:
223  Game::Rescan();
224  break;
225 
229  break;
230 
234  break;
235 
239  break;
240 
241  case CONTENT_TYPE_NEWGRF:
242  ScanNewGRFFiles(NULL);
243  break;
244 
247  extern void ScanScenarios();
248  ScanScenarios();
250  break;
251 
252  default:
253  break;
254  }
255  }
256 
257  /* Always invalidate the download window; tell it we are going to be gone */
259  }
260 
261  virtual void OnClick(Point pt, int widget, int click_count)
262  {
263  if (widget == WID_NCDS_CANCELOK) {
264  if (this->downloaded_bytes != this->total_bytes) {
266  delete this;
267  } else {
268  /* If downloading succeeded, close the online content window. This will close
269  * the current window as well. */
271  }
272  }
273  }
274 
275  virtual void OnDownloadProgress(const ContentInfo *ci, int bytes)
276  {
278  this->receivedTypes.Include(ci->type);
279 
280  /* When downloading is finished change cancel in ok */
281  if (this->downloaded_bytes == this->total_bytes) {
282  this->GetWidget<NWidgetCore>(WID_NCDS_CANCELOK)->widget_data = STR_BUTTON_OK;
283  }
284  }
285 };
286 
290  std::bitset<CONTENT_TYPE_END> types;
291 };
292 
297 };
298 
303 
304  static const uint EDITBOX_MAX_SIZE = 50;
305 
308  static GUIContentList::SortFunction * const sorter_funcs[];
309  static GUIContentList::FilterFunction * const filter_funcs[];
310  GUIContentList content;
311  bool auto_select;
315 
317  int list_pos;
320 
321  static char content_type_strs[CONTENT_TYPE_END][64];
322 
325  {
326  extern void OpenBrowser(const char *url);
327 
328  char url[1024];
329  const char *last = lastof(url);
330 
331  char *pos = strecpy(url, "http://grfsearch.openttd.org/?", last);
332 
333  if (this->auto_select) {
334  pos = strecpy(pos, "do=searchgrfid&q=", last);
335 
336  bool first = true;
337  for (ConstContentIterator iter = this->content.Begin(); iter != this->content.End(); iter++) {
338  const ContentInfo *ci = *iter;
339  if (ci->state != ContentInfo::DOES_NOT_EXIST) continue;
340 
341  if (!first) pos = strecpy(pos, ",", last);
342  first = false;
343 
344  pos += seprintf(pos, last, "%08X", ci->unique_id);
345  pos = strecpy(pos, ":", last);
346  pos = md5sumToString(pos, last, ci->md5sum);
347  }
348  } else {
349  pos = strecpy(pos, "do=searchtext&q=", last);
350 
351  /* Escape search term */
352  for (const char *search = this->filter_editbox.text.buf; *search != '\0'; search++) {
353  /* Remove quotes */
354  if (*search == '\'' || *search == '"') continue;
355 
356  /* Escape special chars, such as &%,= */
357  if (*search < 0x30) {
358  pos += seprintf(pos, last, "%%%02X", *search);
359  } else if (pos < last) {
360  *pos = *search;
361  *++pos = '\0';
362  }
363  }
364  }
365 
366  OpenBrowser(url);
367  }
368 
372  static void ExternalSearchDisclaimerCallback(Window *w, bool accepted)
373  {
374  if (accepted) {
376  ((NetworkContentListWindow*)w)->OpenExternalSearch();
377  }
378  }
379 
385  {
386  if (!this->content.NeedRebuild()) return;
387 
388  /* Create temporary array of games to use for listing */
389  this->content.Clear();
390 
391  bool all_available = true;
392 
394  if ((*iter)->state == ContentInfo::DOES_NOT_EXIST) all_available = false;
395  *this->content.Append() = *iter;
396  }
397 
398  this->SetWidgetDisabledState(WID_NCL_SEARCH_EXTERNAL, this->auto_select && all_available);
399 
400  this->FilterContentList();
401  this->content.Compact();
402  this->content.RebuildDone();
403  this->SortContentList();
404 
405  this->vscroll->SetCount(this->content.Length()); // Update the scrollbar
406  this->ScrollToSelected();
407  }
408 
410  static int CDECL NameSorter(const ContentInfo * const *a, const ContentInfo * const *b)
411  {
412  return strnatcmp((*a)->name, (*b)->name, true); // Sort by name (natural sorting).
413  }
414 
416  static int CDECL TypeSorter(const ContentInfo * const *a, const ContentInfo * const *b)
417  {
418  int r = 0;
419  if ((*a)->type != (*b)->type) {
420  r = strnatcmp(content_type_strs[(*a)->type], content_type_strs[(*b)->type]);
421  }
422  if (r == 0) r = NameSorter(a, b);
423  return r;
424  }
425 
427  static int CDECL StateSorter(const ContentInfo * const *a, const ContentInfo * const *b)
428  {
429  int r = (*a)->state - (*b)->state;
430  if (r == 0) r = TypeSorter(a, b);
431  return r;
432  }
433 
436  {
437  if (!this->content.Sort()) return;
438 
439  for (ConstContentIterator iter = this->content.Begin(); iter != this->content.End(); iter++) {
440  if (*iter == this->selected) {
441  this->list_pos = iter - this->content.Begin();
442  break;
443  }
444  }
445  }
446 
448  static bool CDECL TagNameFilter(const ContentInfo * const *a, ContentListFilterData &filter)
449  {
450  filter.string_filter.ResetState();
451  for (int i = 0; i < (*a)->tag_count; i++) {
452  filter.string_filter.AddLine((*a)->tags[i]);
453  }
454  filter.string_filter.AddLine((*a)->name);
455  return filter.string_filter.GetState();
456  }
457 
459  static bool CDECL TypeOrSelectedFilter(const ContentInfo * const *a, ContentListFilterData &filter)
460  {
461  if (filter.types.none()) return true;
462  if (filter.types[(*a)->type]) return true;
463  return ((*a)->state == ContentInfo::SELECTED || (*a)->state == ContentInfo::AUTOSELECTED);
464  }
465 
468  {
469  /* Apply filters. */
470  bool changed = false;
471  if (!this->filter_data.string_filter.IsEmpty()) {
472  this->content.SetFilterType(CONTENT_FILTER_TEXT);
473  changed |= this->content.Filter(this->filter_data);
474  }
475  if (this->filter_data.types.any()) {
477  changed |= this->content.Filter(this->filter_data);
478  }
479  if (!changed) return;
480 
481  /* update list position */
482  for (ConstContentIterator iter = this->content.Begin(); iter != this->content.End(); iter++) {
483  if (*iter == this->selected) {
484  this->list_pos = iter - this->content.Begin();
485  return;
486  }
487  }
488 
489  /* previously selected item not in list anymore */
490  this->selected = NULL;
491  this->list_pos = 0;
492  }
493 
499  {
500  Filtering old_params = this->content.GetFiltering();
501  bool new_state = !this->filter_data.string_filter.IsEmpty() || this->filter_data.types.any();
502  if (new_state != old_params.state) {
503  this->content.SetFilterState(new_state);
504  }
505  return new_state != old_params.state;
506  }
507 
510  {
511  if (this->selected == NULL) return;
512 
513  this->vscroll->ScrollTowards(this->list_pos);
514  }
515 
516  friend void BuildContentTypeStringList();
517 public:
527  NetworkContentListWindow(WindowDesc *desc, bool select_all, const std::bitset<CONTENT_TYPE_END> &types) :
528  Window(desc),
529  auto_select(select_all),
530  filter_editbox(EDITBOX_MAX_SIZE),
531  selected(NULL),
532  list_pos(0)
533  {
534  this->checkbox_size = maxdim(maxdim(GetSpriteSize(SPR_BOX_EMPTY), GetSpriteSize(SPR_BOX_CHECKED)), GetSpriteSize(SPR_BLOT));
535 
536  this->CreateNestedTree();
537  this->vscroll = this->GetScrollbar(WID_NCL_SCROLLBAR);
539 
540  this->GetWidget<NWidgetStacked>(WID_NCL_SEL_ALL_UPDATE)->SetDisplayedPlane(select_all);
541 
542  this->querystrings[WID_NCL_FILTER] = &this->filter_editbox;
543  this->filter_editbox.cancel_button = QueryString::ACTION_CLEAR;
545  this->SetWidgetDisabledState(WID_NCL_SEARCH_EXTERNAL, this->auto_select);
546  this->filter_data.types = types;
547 
549  this->content.SetListing(this->last_sorting);
550  this->content.SetFiltering(this->last_filtering);
551  this->content.SetSortFuncs(this->sorter_funcs);
552  this->content.SetFilterFuncs(this->filter_funcs);
553  this->UpdateFilterState();
554  this->content.ForceRebuild();
555  this->FilterContentList();
556  this->SortContentList();
557  this->InvalidateData();
558  }
559 
562  {
564  }
565 
566  virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
567  {
568  switch (widget) {
569  case WID_NCL_FILTER_CAPT:
570  *size = maxdim(*size, GetStringBoundingBox(STR_CONTENT_FILTER_TITLE));
571  break;
572 
573  case WID_NCL_CHECKBOX:
574  size->width = this->checkbox_size.width + WD_MATRIX_RIGHT + WD_MATRIX_LEFT;
575  break;
576 
577  case WID_NCL_TYPE: {
578  Dimension d = *size;
579  for (int i = CONTENT_TYPE_BEGIN; i < CONTENT_TYPE_END; i++) {
580  d = maxdim(d, GetStringBoundingBox(STR_CONTENT_TYPE_BASE_GRAPHICS + i - CONTENT_TYPE_BASE_GRAPHICS));
581  }
582  size->width = d.width + WD_MATRIX_RIGHT + WD_MATRIX_LEFT;
583  break;
584  }
585 
586  case WID_NCL_MATRIX:
587  resize->height = max(this->checkbox_size.height, (uint)FONT_HEIGHT_NORMAL) + WD_MATRIX_TOP + WD_MATRIX_BOTTOM;
588  size->height = 10 * resize->height;
589  break;
590  }
591  }
592 
593 
594  virtual void DrawWidget(const Rect &r, int widget) const
595  {
596  switch (widget) {
597  case WID_NCL_FILTER_CAPT:
598  DrawString(r.left, r.right, r.top, STR_CONTENT_FILTER_TITLE, TC_FROMSTRING, SA_RIGHT);
599  break;
600 
601  case WID_NCL_DETAILS:
602  this->DrawDetails(r);
603  break;
604 
605  case WID_NCL_MATRIX:
606  this->DrawMatrix(r);
607  break;
608  }
609  }
610 
611  virtual void OnPaint()
612  {
613  const SortButtonState arrow = this->content.IsDescSortOrder() ? SBS_DOWN : SBS_UP;
614 
615  if (this->content.NeedRebuild()) {
616  this->BuildContentList();
617  }
618 
619  this->DrawWidgets();
620 
621  switch (this->content.SortType()) {
623  case WID_NCL_TYPE - WID_NCL_CHECKBOX: this->DrawSortButtonState(WID_NCL_TYPE, arrow); break;
624  case WID_NCL_NAME - WID_NCL_CHECKBOX: this->DrawSortButtonState(WID_NCL_NAME, arrow); break;
625  }
626  }
627 
632  void DrawMatrix(const Rect &r) const
633  {
634  const NWidgetBase *nwi_checkbox = this->GetWidget<NWidgetBase>(WID_NCL_CHECKBOX);
635  const NWidgetBase *nwi_name = this->GetWidget<NWidgetBase>(WID_NCL_NAME);
636  const NWidgetBase *nwi_type = this->GetWidget<NWidgetBase>(WID_NCL_TYPE);
637 
638  int line_height = max(this->checkbox_size.height, (uint)FONT_HEIGHT_NORMAL);
639 
640  /* Fill the matrix with the information */
641  int sprite_y_offset = WD_MATRIX_TOP + (line_height - this->checkbox_size.height) / 2 - 1;
642  int text_y_offset = WD_MATRIX_TOP + (line_height - FONT_HEIGHT_NORMAL) / 2;
643  uint y = r.top;
644  int cnt = 0;
645  for (ConstContentIterator iter = this->content.Get(this->vscroll->GetPosition()); iter != this->content.End() && cnt < this->vscroll->GetCapacity(); iter++, cnt++) {
646  const ContentInfo *ci = *iter;
647 
648  if (ci == this->selected) GfxFillRect(r.left + 1, y + 1, r.right - 1, y + this->resize.step_height - 1, PC_GREY);
649 
650  SpriteID sprite;
651  SpriteID pal = PAL_NONE;
652  switch (ci->state) {
653  case ContentInfo::UNSELECTED: sprite = SPR_BOX_EMPTY; break;
654  case ContentInfo::SELECTED: sprite = SPR_BOX_CHECKED; break;
655  case ContentInfo::AUTOSELECTED: sprite = SPR_BOX_CHECKED; break;
656  case ContentInfo::ALREADY_HERE: sprite = SPR_BLOT; pal = PALETTE_TO_GREEN; break;
657  case ContentInfo::DOES_NOT_EXIST: sprite = SPR_BLOT; pal = PALETTE_TO_RED; break;
658  default: NOT_REACHED();
659  }
660  DrawSprite(sprite, pal, nwi_checkbox->pos_x + (pal == PAL_NONE ? 2 : 3), y + sprite_y_offset + (pal == PAL_NONE ? 1 : 0));
661 
662  StringID str = STR_CONTENT_TYPE_BASE_GRAPHICS + ci->type - CONTENT_TYPE_BASE_GRAPHICS;
663  DrawString(nwi_type->pos_x, nwi_type->pos_x + nwi_type->current_x - 1, y + text_y_offset, str, TC_BLACK, SA_HOR_CENTER);
664 
665  DrawString(nwi_name->pos_x + WD_FRAMERECT_LEFT, nwi_name->pos_x + nwi_name->current_x - WD_FRAMERECT_RIGHT, y + text_y_offset, ci->name, TC_BLACK);
666  y += this->resize.step_height;
667  }
668  }
669 
674  void DrawDetails(const Rect &r) const
675  {
676  static const int DETAIL_LEFT = 5;
677  static const int DETAIL_RIGHT = 5;
678  static const int DETAIL_TOP = 5;
679 
680  /* Height for the title banner */
681  int DETAIL_TITLE_HEIGHT = 5 * FONT_HEIGHT_NORMAL;
682 
683  /* Create the nice grayish rectangle at the details top */
684  GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.top + DETAIL_TITLE_HEIGHT, PC_DARK_BLUE);
685  DrawString(r.left + WD_INSET_LEFT, r.right - WD_INSET_RIGHT, r.top + FONT_HEIGHT_NORMAL + WD_INSET_TOP, STR_CONTENT_DETAIL_TITLE, TC_FROMSTRING, SA_HOR_CENTER);
686 
687  /* Draw the total download size */
688  SetDParam(0, this->filesize_sum);
689  DrawString(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, r.bottom - FONT_HEIGHT_NORMAL - WD_PAR_VSEP_NORMAL, STR_CONTENT_TOTAL_DOWNLOAD_SIZE);
690 
691  if (this->selected == NULL) return;
692 
693  /* And fill the rest of the details when there's information to place there */
694  DrawStringMultiLine(r.left + WD_INSET_LEFT, r.right - WD_INSET_RIGHT, r.top + DETAIL_TITLE_HEIGHT / 2, r.top + DETAIL_TITLE_HEIGHT, STR_CONTENT_DETAIL_SUBTITLE_UNSELECTED + this->selected->state, TC_FROMSTRING, SA_CENTER);
695 
696  /* Also show the total download size, so keep some space from the bottom */
697  const uint max_y = r.bottom - FONT_HEIGHT_NORMAL - WD_PAR_VSEP_WIDE;
698  int y = r.top + DETAIL_TITLE_HEIGHT + DETAIL_TOP;
699 
700  if (this->selected->upgrade) {
701  SetDParam(0, STR_CONTENT_TYPE_BASE_GRAPHICS + this->selected->type - CONTENT_TYPE_BASE_GRAPHICS);
702  y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_UPDATE);
703  y += WD_PAR_VSEP_WIDE;
704  }
705 
706  SetDParamStr(0, this->selected->name);
707  y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_NAME);
708 
709  if (!StrEmpty(this->selected->version)) {
710  SetDParamStr(0, this->selected->version);
711  y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_VERSION);
712  }
713 
714  if (!StrEmpty(this->selected->description)) {
715  SetDParamStr(0, this->selected->description);
716  y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_DESCRIPTION);
717  }
718 
719  if (!StrEmpty(this->selected->url)) {
720  SetDParamStr(0, this->selected->url);
721  y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_URL);
722  }
723 
724  SetDParam(0, STR_CONTENT_TYPE_BASE_GRAPHICS + this->selected->type - CONTENT_TYPE_BASE_GRAPHICS);
725  y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_TYPE);
726 
727  y += WD_PAR_VSEP_WIDE;
728  SetDParam(0, this->selected->filesize);
729  y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_FILESIZE);
730 
731  if (this->selected->dependency_count != 0) {
732  /* List dependencies */
733  char buf[DRAW_STRING_BUFFER] = "";
734  char *p = buf;
735  for (uint i = 0; i < this->selected->dependency_count; i++) {
736  ContentID cid = this->selected->dependencies[i];
737 
738  /* Try to find the dependency */
740  for (; iter != _network_content_client.End(); iter++) {
741  const ContentInfo *ci = *iter;
742  if (ci->id != cid) continue;
743 
744  p += seprintf(p, lastof(buf), p == buf ? "%s" : ", %s", (*iter)->name);
745  break;
746  }
747  }
748  SetDParamStr(0, buf);
749  y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_DEPENDENCIES);
750  }
751 
752  if (this->selected->tag_count != 0) {
753  /* List all tags */
754  char buf[DRAW_STRING_BUFFER] = "";
755  char *p = buf;
756  for (uint i = 0; i < this->selected->tag_count; i++) {
757  p += seprintf(p, lastof(buf), i == 0 ? "%s" : ", %s", this->selected->tags[i]);
758  }
759  SetDParamStr(0, buf);
760  y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_TAGS);
761  }
762 
763  if (this->selected->IsSelected()) {
764  /* When selected show all manually selected content that depends on this */
765  ConstContentVector tree;
767 
768  char buf[DRAW_STRING_BUFFER] = "";
769  char *p = buf;
770  for (ConstContentIterator iter = tree.Begin(); iter != tree.End(); iter++) {
771  const ContentInfo *ci = *iter;
772  if (ci == this->selected || ci->state != ContentInfo::SELECTED) continue;
773 
774  p += seprintf(p, lastof(buf), buf == p ? "%s" : ", %s", ci->name);
775  }
776  if (p != buf) {
777  SetDParamStr(0, buf);
778  y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_SELECTED_BECAUSE_OF);
779  }
780  }
781  }
782 
783  virtual void OnClick(Point pt, int widget, int click_count)
784  {
785  if (widget >= WID_NCL_TEXTFILE && widget < WID_NCL_TEXTFILE + TFT_END) {
786  if (this->selected == NULL || this->selected->state != ContentInfo::ALREADY_HERE) return;
787 
788  ShowContentTextfileWindow((TextfileType)(widget - WID_NCL_TEXTFILE), this->selected);
789  return;
790  }
791 
792  switch (widget) {
793  case WID_NCL_MATRIX: {
794  uint id_v = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_NCL_MATRIX);
795  if (id_v >= this->content.Length()) return; // click out of bounds
796 
797  this->selected = *this->content.Get(id_v);
798  this->list_pos = id_v;
799 
800  const NWidgetBase *checkbox = this->GetWidget<NWidgetBase>(WID_NCL_CHECKBOX);
801  if (click_count > 1 || IsInsideBS(pt.x, checkbox->pos_x, checkbox->current_x)) {
803  this->content.ForceResort();
804  }
805 
806  if (this->filter_data.types.any()) {
807  this->content.ForceRebuild();
808  }
809 
810  this->InvalidateData();
811  break;
812  }
813 
814  case WID_NCL_CHECKBOX:
815  case WID_NCL_TYPE:
816  case WID_NCL_NAME:
817  if (this->content.SortType() == widget - WID_NCL_CHECKBOX) {
818  this->content.ToggleSortOrder();
819  if (this->content.Length() > 0) this->list_pos = this->content.Length() - this->list_pos - 1;
820  } else {
821  this->content.SetSortType(widget - WID_NCL_CHECKBOX);
822  this->content.ForceResort();
823  this->SortContentList();
824  }
825  this->ScrollToSelected();
826  this->InvalidateData();
827  break;
828 
829  case WID_NCL_SELECT_ALL:
831  this->InvalidateData();
832  break;
833 
836  this->InvalidateData();
837  break;
838 
839  case WID_NCL_UNSELECT:
841  this->InvalidateData();
842  break;
843 
844  case WID_NCL_CANCEL:
845  delete this;
846  break;
847 
848  case WID_NCL_OPEN_URL:
849  if (this->selected != NULL) {
850  extern void OpenBrowser(const char *url);
851  OpenBrowser(this->selected->url);
852  }
853  break;
854 
855  case WID_NCL_DOWNLOAD:
857  break;
858 
861  this->OpenExternalSearch();
862  } else {
863  ShowQuery(STR_CONTENT_SEARCH_EXTERNAL_DISCLAIMER_CAPTION, STR_CONTENT_SEARCH_EXTERNAL_DISCLAIMER, this, ExternalSearchDisclaimerCallback);
864  }
865  break;
866  }
867  }
868 
869  virtual EventState OnKeyPress(WChar key, uint16 keycode)
870  {
871  switch (keycode) {
872  case WKC_UP:
873  /* scroll up by one */
874  if (this->list_pos > 0) this->list_pos--;
875  break;
876  case WKC_DOWN:
877  /* scroll down by one */
878  if (this->list_pos < (int)this->content.Length() - 1) this->list_pos++;
879  break;
880  case WKC_PAGEUP:
881  /* scroll up a page */
882  this->list_pos = (this->list_pos < this->vscroll->GetCapacity()) ? 0 : this->list_pos - this->vscroll->GetCapacity();
883  break;
884  case WKC_PAGEDOWN:
885  /* scroll down a page */
886  this->list_pos = min(this->list_pos + this->vscroll->GetCapacity(), (int)this->content.Length() - 1);
887  break;
888  case WKC_HOME:
889  /* jump to beginning */
890  this->list_pos = 0;
891  break;
892  case WKC_END:
893  /* jump to end */
894  this->list_pos = this->content.Length() - 1;
895  break;
896 
897  case WKC_SPACE:
898  case WKC_RETURN:
899  if (keycode == WKC_RETURN || !IsWidgetFocused(WID_NCL_FILTER)) {
900  if (this->selected != NULL) {
902  this->content.ForceResort();
903  this->InvalidateData();
904  }
905  if (this->filter_data.types.any()) {
906  this->content.ForceRebuild();
907  this->InvalidateData();
908  }
909  return ES_HANDLED;
910  }
911  /* space is pressed and filter is focused. */
912  FALLTHROUGH;
913 
914  default:
915  return ES_NOT_HANDLED;
916  }
917 
918  if (this->content.Length() == 0) {
919  this->list_pos = 0; // above stuff may result in "-1".
920  if (this->UpdateFilterState()) {
921  this->content.ForceRebuild();
922  this->InvalidateData();
923  }
924  return ES_HANDLED;
925  }
926 
927  this->selected = *this->content.Get(this->list_pos);
928 
929  if (this->UpdateFilterState()) {
930  this->content.ForceRebuild();
931  } else {
932  /* Scroll to the new content if it is outside the current range. */
933  this->ScrollToSelected();
934  }
935 
936  /* redraw window */
937  this->InvalidateData();
938  return ES_HANDLED;
939  }
940 
941  virtual void OnEditboxChanged(int wid)
942  {
943  if (wid == WID_NCL_FILTER) {
944  this->filter_data.string_filter.SetFilterTerm(this->filter_editbox.text.buf);
945  this->UpdateFilterState();
946  this->content.ForceRebuild();
947  this->InvalidateData();
948  }
949  }
950 
951  virtual void OnResize()
952  {
953  this->vscroll->SetCapacityFromWidget(this, WID_NCL_MATRIX);
954  }
955 
956  virtual void OnReceiveContentInfo(const ContentInfo *rci)
957  {
958  if (this->auto_select && !rci->IsSelected()) _network_content_client.ToggleSelectedState(rci);
959  this->content.ForceRebuild();
960  this->InvalidateData();
961  }
962 
963  virtual void OnDownloadComplete(ContentID cid)
964  {
965  this->content.ForceResort();
966  this->InvalidateData();
967  }
968 
969  virtual void OnConnect(bool success)
970  {
971  if (!success) {
972  ShowErrorMessage(STR_CONTENT_ERROR_COULD_NOT_CONNECT, INVALID_STRING_ID, WL_ERROR);
973  delete this;
974  return;
975  }
976 
977  this->InvalidateData();
978  }
979 
985  virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
986  {
987  if (!gui_scope) return;
988  if (this->content.NeedRebuild()) this->BuildContentList();
989 
990  /* To sum all the bytes we intend to download */
991  this->filesize_sum = 0;
992  bool show_select_all = false;
993  bool show_select_upgrade = false;
994  for (ConstContentIterator iter = this->content.Begin(); iter != this->content.End(); iter++) {
995  const ContentInfo *ci = *iter;
996  switch (ci->state) {
999  this->filesize_sum += ci->filesize;
1000  break;
1001 
1003  show_select_all = true;
1004  show_select_upgrade |= ci->upgrade;
1005  break;
1006 
1007  default:
1008  break;
1009  }
1010  }
1011 
1012  /* If data == 2 then the status window caused this OnInvalidate */
1014  this->SetWidgetDisabledState(WID_NCL_UNSELECT, this->filesize_sum == 0);
1015  this->SetWidgetDisabledState(WID_NCL_SELECT_ALL, !show_select_all);
1016  this->SetWidgetDisabledState(WID_NCL_SELECT_UPDATE, !show_select_upgrade);
1017  this->SetWidgetDisabledState(WID_NCL_OPEN_URL, this->selected == NULL || StrEmpty(this->selected->url));
1018  for (TextfileType tft = TFT_BEGIN; tft < TFT_END; tft++) {
1019  this->SetWidgetDisabledState(WID_NCL_TEXTFILE + tft, this->selected == NULL || this->selected->state != ContentInfo::ALREADY_HERE || this->selected->GetTextfile(tft) == NULL);
1020  }
1021 
1022  this->GetWidget<NWidgetCore>(WID_NCL_CANCEL)->widget_data = this->filesize_sum == 0 ? STR_AI_SETTINGS_CLOSE : STR_AI_LIST_CANCEL;
1023  }
1024 };
1025 
1028 
1030  &StateSorter,
1031  &TypeSorter,
1032  &NameSorter,
1033 };
1034 
1036  &TagNameFilter,
1037  &TypeOrSelectedFilter,
1038 };
1039 
1041 
1046 {
1047  for (int i = CONTENT_TYPE_BEGIN; i < CONTENT_TYPE_END; i++) {
1049  }
1050 }
1051 
1055  NWidget(WWT_CLOSEBOX, COLOUR_LIGHT_BLUE),
1056  NWidget(WWT_CAPTION, COLOUR_LIGHT_BLUE), SetDataTip(STR_CONTENT_TITLE, STR_NULL),
1057  NWidget(WWT_DEFSIZEBOX, COLOUR_LIGHT_BLUE),
1058  EndContainer(),
1059  NWidget(WWT_PANEL, COLOUR_LIGHT_BLUE, WID_NCL_BACKGROUND),
1062  /* Top */
1063  NWidget(WWT_EMPTY, COLOUR_LIGHT_BLUE, WID_NCL_FILTER_CAPT), SetFill(1, 0), SetResize(1, 0),
1064  NWidget(WWT_EDITBOX, COLOUR_LIGHT_BLUE, WID_NCL_FILTER), SetFill(1, 0), SetResize(1, 0),
1065  SetDataTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP),
1066  EndContainer(),
1069  /* Left side. */
1070  NWidget(NWID_VERTICAL), SetPIP(0, 4, 0),
1074  NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NCL_CHECKBOX), SetMinimalSize(13, 1), SetDataTip(STR_EMPTY, STR_NULL),
1075  NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NCL_TYPE),
1076  SetDataTip(STR_CONTENT_TYPE_CAPTION, STR_CONTENT_TYPE_CAPTION_TOOLTIP),
1077  NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NCL_NAME), SetResize(1, 0), SetFill(1, 0),
1078  SetDataTip(STR_CONTENT_NAME_CAPTION, STR_CONTENT_NAME_CAPTION_TOOLTIP),
1079  EndContainer(),
1080  NWidget(WWT_MATRIX, COLOUR_LIGHT_BLUE, WID_NCL_MATRIX), SetResize(1, 14), SetFill(1, 1), SetScrollbar(WID_NCL_SCROLLBAR), SetMatrixDataTip(1, 0, STR_CONTENT_MATRIX_TOOLTIP),
1081  EndContainer(),
1082  NWidget(NWID_VSCROLLBAR, COLOUR_LIGHT_BLUE, WID_NCL_SCROLLBAR),
1083  EndContainer(),
1085  NWidget(NWID_SELECTION, INVALID_COLOUR, WID_NCL_SEL_ALL_UPDATE), SetResize(1, 0), SetFill(1, 0),
1086  NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NCL_SELECT_UPDATE), SetResize(1, 0), SetFill(1, 0),
1087  SetDataTip(STR_CONTENT_SELECT_UPDATES_CAPTION, STR_CONTENT_SELECT_UPDATES_CAPTION_TOOLTIP),
1088  NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NCL_SELECT_ALL), SetResize(1, 0), SetFill(1, 0),
1089  SetDataTip(STR_CONTENT_SELECT_ALL_CAPTION, STR_CONTENT_SELECT_ALL_CAPTION_TOOLTIP),
1090  EndContainer(),
1091  NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NCL_UNSELECT), SetResize(1, 0), SetFill(1, 0),
1092  SetDataTip(STR_CONTENT_UNSELECT_ALL_CAPTION, STR_CONTENT_UNSELECT_ALL_CAPTION_TOOLTIP),
1093  EndContainer(),
1094  EndContainer(),
1095  /* Right side. */
1096  NWidget(NWID_VERTICAL), SetPIP(0, 4, 0),
1097  NWidget(WWT_PANEL, COLOUR_LIGHT_BLUE, WID_NCL_DETAILS), SetResize(1, 1), SetFill(1, 1), EndContainer(),
1099  NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NCL_TEXTFILE + TFT_README), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_README, STR_NULL),
1100  NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NCL_TEXTFILE + TFT_CHANGELOG), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_CHANGELOG, STR_NULL),
1101  EndContainer(),
1103  NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NCL_OPEN_URL), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_CONTENT_OPEN_URL, STR_CONTENT_OPEN_URL_TOOLTIP),
1104  NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NCL_TEXTFILE + TFT_LICENSE), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_LICENCE, STR_NULL),
1105  EndContainer(),
1106  EndContainer(),
1107  EndContainer(),
1109  /* Bottom. */
1111  NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NCL_SEARCH_EXTERNAL), SetResize(1, 0), SetFill(1, 0),
1112  SetDataTip(STR_CONTENT_SEARCH_EXTERNAL, STR_CONTENT_SEARCH_EXTERNAL_TOOLTIP),
1114  NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NCL_CANCEL), SetResize(1, 0), SetFill(1, 0),
1115  SetDataTip(STR_BUTTON_CANCEL, STR_NULL),
1116  NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NCL_DOWNLOAD), SetResize(1, 0), SetFill(1, 0),
1117  SetDataTip(STR_CONTENT_DOWNLOAD_CAPTION, STR_CONTENT_DOWNLOAD_CAPTION_TOOLTIP),
1118  EndContainer(),
1119  EndContainer(),
1121  /* Resize button. */
1123  NWidget(NWID_SPACER), SetFill(1, 0), SetResize(1, 0),
1124  NWidget(WWT_RESIZEBOX, COLOUR_LIGHT_BLUE),
1125  EndContainer(),
1126  EndContainer(),
1127 };
1128 
1131  WDP_CENTER, "list_content", 630, 460,
1133  0,
1134  _nested_network_content_list_widgets, lengthof(_nested_network_content_list_widgets)
1135 );
1136 
1145 {
1146 #if defined(WITH_ZLIB)
1147  std::bitset<CONTENT_TYPE_END> types;
1149  if (cv == NULL) {
1150  assert(type1 != CONTENT_TYPE_END || type2 == CONTENT_TYPE_END);
1151  assert(type1 == CONTENT_TYPE_END || type1 != type2);
1154 
1155  if (type1 != CONTENT_TYPE_END) types[type1] = true;
1156  if (type2 != CONTENT_TYPE_END) types[type2] = true;
1157  } else {
1159  }
1160 
1162  new NetworkContentListWindow(&_network_content_list_desc, cv != NULL, types);
1163 #else
1164  ShowErrorMessage(STR_CONTENT_NO_ZLIB, STR_CONTENT_NO_ZLIB_SUB, WL_ERROR);
1165  /* Connection failed... clean up the mess */
1166  if (cv != NULL) {
1167  for (ContentIterator iter = cv->Begin(); iter != cv->End(); iter++) delete *iter;
1168  }
1169 #endif /* WITH_ZLIB */
1170 }
1171 
1172 #endif /* ENABLE_NETWORK */
EventState
State of handling an event.
Definition: window_type.h:701
static WindowDesc _network_content_list_desc(WDP_CENTER, "list_content", 630, 460, WC_NETWORK_WINDOW, WC_NONE, 0, _nested_network_content_list_widgets, lengthof(_nested_network_content_list_widgets))
Window description of the content list.
Helper to mark the end of the types.
Definition: tcp_content.h:37
Empty widget, place holder to reserve space in widget array.
Definition: widget_type.h:48
const ContentInfo *const * ConstContentIterator
Iterator for the constant content vector.
void RebuildDone()
Notify the sortlist that the rebuild is done.
The content consists of base graphics.
Definition: tcp_content.h:27
Panel with content details.
bool IsSelected() const
Is the state either selected or autoselected?
Definition: tcp_content.cpp:77
void DownloadSelectedContent(uint &files, uint &bytes, bool fallback=false)
Actually begin downloading the content we selected.
char filename[48]
Filename (for the .tar.gz; only valid on download)
Definition: tcp_content.h:72
ConstContentIterator Begin() const
Get the begin of the content inf iterator.
~BaseNetworkContentDownloadStatusWindow()
Free everything associated with this window.
Horizontally center the text.
Definition: gfx_func.h:99
ResizeInfo resize
Resize information.
Definition: window_gui.h:317
static bool _accepted_external_search
Whether the user accepted to enter external websites during this session.
Panel with list of content.
Scan for base sets.
Definition: fileio_func.h:101
void ScrollTowards(int position)
Scroll towards the given position; if the item is visible nothing happens, otherwise it will be shown...
Definition: widget_type.h:731
static NWidgetPart SetResize(int16 dx, int16 dy)
Widget part function for setting the resize step.
Definition: widget_type.h:930
virtual void OnResize()
Called after the window got resized.
Window that lists the content that&#39;s at the content server.
uint32 unique_id
Unique ID; either GRF ID or shortname.
Definition: tcp_content.h:77
void GfxFillRect(int left, int top, int right, int bottom, int colour, FillRectMode mode)
Applies a certain FillRectMode-operation to a rectangle [left, right] x [top, bottom] on the screen...
Definition: gfx.cpp:112
void SetWidgetDisabledState(byte widget_index, bool disab_stat)
Sets the enabled/disabled status of a widget.
Definition: window_gui.h:387
Offset at right of a matrix cell.
Definition: window_gui.h:79
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting)
Definition: window.cpp:3120
Window * parent
Parent window.
Definition: window_gui.h:332
void Close()
Disconnect from the content server.
const ContentInfo * selected
The selected content info.
High level window description.
Definition: window_gui.h:168
Saveload window; Window numbers:
Definition: window_type.h:139
bool Filter(FilterFunction *decide, F filter_data)
Filter the list.
void DrawWidgets() const
Paint all widgets of a window.
Definition: widget.cpp:604
static uint FindSets()
Do the scan for files.
Scrollbar data structure.
Definition: widget_type.h:589
virtual void OnPaint()
The window must be repainted.
int CDECL seprintf(char *str, const char *last, const char *format,...)
Safer implementation of snprintf; same as snprintf except:
Definition: string.cpp:398
static void DrawMatrix(const Rect &r, Colours colour, bool clicked, uint16 data, uint resize_x, uint resize_y)
Draw a matrix widget.
Definition: widget.cpp:278
Offset at top to draw the frame rectangular area.
Definition: window_gui.h:64
Dimension checkbox_size
Size of checkbox/"blot" sprite.
Normal amount of vertical space between two paragraphs of text.
Definition: window_gui.h:139
textfile; Window numbers:
Definition: window_type.h:182
Horizontal container.
Definition: widget_type.h:75
Window * FindWindowById(WindowClass cls, WindowNumber number)
Find a window by its class and window number.
Definition: window.cpp:1105
void ResetState()
Reset the matching state to process a new item.
The passed event is not handled.
Definition: window_type.h:703
void SetSortFuncs(SortFunction *const *n_funcs)
Hand the array of sort function pointers to the sort list.
bool GetState() const
Get the matching state of the current item.
Callbacks for notifying others about incoming data.
Filter data for NetworkContentListWindow.
uint32 filesize
Size of the file.
Definition: tcp_content.h:71
The content consists of a scenario.
Definition: tcp_content.h:31
uint8 dependency_count
Number of dependencies.
Definition: tcp_content.h:79
&#39;Name&#39; button.
char(* tags)[32]
Malloced array of tags (strings)
Definition: tcp_content.h:82
char * md5sumToString(char *buf, const char *last, const uint8 md5sum[16])
Convert the md5sum to a hexadecimal string representation.
Definition: string.cpp:416
a textbox for typing
Definition: widget_type.h:71
Resize box (normally at bottom-right of a window)
Definition: widget_type.h:68
void SetFilterType(uint8 n_type)
Set the filtertype of the list.
static const int ACTION_CLEAR
Clear editbox.
NewGRF changelog.
Definition: textfile_type.h:20
static bool IsInsideBS(const T x, const uint base, const uint size)
Checks if a value is between a window started at some base point.
Definition: math_func.hpp:250
void Clear()
Remove all items from the list.
void ReverseLookupTreeDependency(ConstContentVector &tree, const ContentInfo *child) const
Reverse lookup the dependencies of all parents over a given child.
void Compact()
Compact the list down to the smallest block size boundary.
const T * Begin() const
Get the pointer to the first item (const)
GUIContentList content
List with content.
ContentID * dependencies
Malloced array of dependencies (unique server side ids)
Definition: tcp_content.h:80
Close box (at top-left of a window)
Definition: widget_type.h:69
virtual void OnClick(Point pt, int widget, int click_count)
A click with the left mouse button has been made on the window.
Scrollbar * vscroll
Cache of the vertical scrollbar.
static const int DRAW_STRING_BUFFER
Size of the buffer used for drawing strings.
Definition: gfx_func.h:87
Offset at top of a matrix cell.
Definition: window_gui.h:80
ContentListFilterData filter_data
Filter for content list.
Scrollbar of matrix.
The content has been selected as dependency.
Definition: tcp_content.h:63
std::bitset< CONTENT_TYPE_END > types
Content types displayed.
static NWidgetPart SetMinimalTextLines(uint8 lines, uint8 spacing, FontSize size=FS_NORMAL)
Widget part function for setting the minimal text lines.
Definition: widget_type.h:965
NetworkContentDownloadStatusWindow()
Create a new download window based on a list of content information with flags whether to download th...
String filter and state.
#define lastof(x)
Get the last element of an fixed size array.
Definition: depend.cpp:50
virtual void OnReceiveContentInfo(const ContentInfo *rci)
We received a content info.
void SetFilterFuncs(FilterFunction *const *n_funcs)
Hand the array of filter function pointers to the sort list.
Filter by query sting.
NewGRF readme.
Definition: textfile_type.h:19
static T max(const T a, const T b)
Returns the maximum of two values.
Definition: math_func.hpp:26
ContentID
Unique identifier for the content.
Definition: tcp_content.h:53
The content has not been selected.
Definition: tcp_content.h:61
const T * End() const
Get the pointer behind the last valid item (const)
void CreateNestedTree(bool fill_nested=true)
Perform the first part of the initialization of a nested widget tree.
Definition: window.cpp:1804
void SetListing(Listing l)
Import sort conditions.
Large amount of vertical space between two paragraphs of text.
Definition: window_gui.h:140
Data structure describing what to show in the list (filter criteria).
Definition: sortlist_type.h:39
Search external sites for missing NewGRF.
bool NeedRebuild() const
Check if a rebuild is needed.
void DrawFrameRect(int left, int top, int right, int bottom, Colours colour, FrameFlags flags)
Draw frame rectangle.
Definition: widget.cpp:177
T * Append(uint to_add=1)
Append an item and return it.
void SetCount(int num)
Sets the number of elements in the list.
Definition: widget_type.h:670
The content does not exist in the content system.
Definition: tcp_content.h:65
Partial widget specification to allow NWidgets to be written nested.
Definition: widget_type.h:910
void ForceRebuild()
Force that a rebuild is needed.
void ScrollToSelected()
Make sure that the currently selected content info is within the visible part of the matrix...
&#39;Cancel&#39; button.
NewGRF license.
Definition: textfile_type.h:21
Data structure for an opened window.
Definition: window_gui.h:271
void UnselectAll()
Unselect everything that we&#39;ve not downloaded so far.
void FinishInitNested(WindowNumber window_number=0)
Perform the second part of the initialization of a nested widget tree.
Definition: window.cpp:1820
static NWidgetPart SetMatrixDataTip(uint8 cols, uint8 rows, StringID tip)
Widget part function for setting the data and tooltip of WWT_MATRIX widgets.
Definition: widget_type.h:1032
void BuildContentTypeStringList()
Build array of all strings corresponding to the content types.
void SetFilterTerm(const char *str)
Set the term to filter on.
void InitNested(WindowNumber number=0)
Perform complete initialization of the Window with nested widgets, to allow use.
Definition: window.cpp:1833
void ShowErrorMessage(StringID summary_msg, StringID detailed_msg, WarningLevel wl, int x=0, int y=0, const GRFFile *textref_stack_grffile=NULL, uint textref_stack_size=0, const uint32 *textref_stack=NULL)
Display an error message in a window.
Definition: error_gui.cpp:378
&#39;Download&#39; button.
void SetDParamStr(uint n, const char *str)
This function is used to "bind" a C string to a OpenTTD dparam slot.
Definition: strings.cpp:279
~NetworkContentDownloadStatusWindow()
Free whatever we&#39;ve allocated.
char name[32]
Name of the content.
Definition: tcp_content.h:73
The content consists of a game script.
Definition: tcp_content.h:35
virtual void DrawWidget(const Rect &r, int widget) const
Draw the contents of a nested widget.
void AddCallback(ContentCallback *cb)
Add a callback to this class.
StringFilter string_filter
Text filter of content list.
Invisible widget that takes some space.
Definition: widget_type.h:79
static void ExternalSearchDisclaimerCallback(Window *w, bool accepted)
Callback function for disclaimer about entering external websites.
ConstContentIterator End() const
Get the end of the content inf iterator.
Offset at bottom of a matrix cell.
Definition: window_gui.h:81
Default window size box (at top-right of a window, between WWT_SHADEBOX and WWT_STICKYBOX) ...
Definition: widget_type.h:65
uint Length() const
Get the number of items in the list.
int GetScrolledRowFromWidget(int clickpos, const Window *const w, int widget, int padding=0, int line_height=-1) const
Compute the row of a scrolled widget that a user clicked in.
Definition: widget.cpp:1959
uint8 tag_count
Number of tags.
Definition: tcp_content.h:81
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
Update size and resize step of a widget in the window.
char version[16]
Version of the content.
Definition: tcp_content.h:74
static bool CDECL TypeOrSelectedFilter(const ContentInfo *const *a, ContentListFilterData &filter)
Filter content by type, but still show content selected for download.
void SelectUpgrade()
Select everything that&#39;s an update for something we&#39;ve got.
void ShowQuery(StringID caption, StringID message, Window *parent, QueryCallbackProc *callback)
Show a modal confirmation window with standard &#39;yes&#39; and &#39;no&#39; buttons The window is aligned to the ce...
Definition: misc_gui.cpp:1206
Sort descending.
Definition: window_gui.h:227
static const NWidgetPart _nested_network_content_list_widgets[]
The widgets for the content list.
SmallMap< int, QueryString * > querystrings
QueryString associated to WWT_EDITBOX widgets.
Definition: window_gui.h:323
#define FONT_HEIGHT_NORMAL
Height of characters in the normal (FS_NORMAL) font.
Definition: gfx_func.h:180
static NWidgetPart SetDataTip(uint32 data, StringID tip)
Widget part function for setting the data and tooltip.
Definition: widget_type.h:1014
NetworkContentListWindow(WindowDesc *desc, bool select_all, const std::bitset< CONTENT_TYPE_END > &types)
Create the content list window.
Data stored about a string that can be modified in the GUI.
Window for displaying the textfile of an item in the content list.
static NWidgetPart SetMinimalSize(int16 x, int16 y)
Widget part function for setting the minimal size.
Definition: widget_type.h:947
Left offset of string.
Definition: window_gui.h:46
Center both horizontally and vertically.
Definition: gfx_func.h:108
The content is already at the client side.
Definition: tcp_content.h:64
ContentID id
Unique (server side) ID for the content.
Definition: tcp_content.h:70
int list_pos
Our position in the list.
static bool CDECL TagNameFilter(const ContentInfo *const *a, ContentListFilterData &filter)
Filter content by tags/name.
Normal push-button (no toggle button) with text caption.
Definition: widget_type.h:104
Simple depressed panel.
Definition: widget_type.h:50
&#39;Unselect all&#39; button.
bool state
Filter on/off.
Definition: sortlist_type.h:40
void ScanScenarios()
Force a (re)scan of the scenarios.
Definition: fios.cpp:774
bool UpdateFilterState()
Update filter state based on current window state.
void Clear()
Clear all downloaded content information.
static const NWidgetPart _nested_network_content_download_status_window_widgets[]
Nested widgets for the download window.
Scan for scenarios and heightmaps.
Definition: fileio_func.h:104
static int CDECL TypeSorter(const ContentInfo *const *a, const ContentInfo *const *b)
Sort content by type.
void DrawSortButtonState(int widget, SortButtonState state) const
Draw a sort button&#39;s up or down arrow symbol.
Definition: widget.cpp:638
uint step_height
Step-size of height resize changes.
Definition: window_gui.h:220
const Scrollbar * GetScrollbar(uint widnum) const
Return the Scrollbar to a widget index.
Definition: window.cpp:307
Offset at left of a matrix cell.
Definition: window_gui.h:78
void RequestContentList(ContentType type)
Request the content list for the given type.
State state
Whether the content info is selected (for download)
Definition: tcp_content.h:83
Background of the window.
Center the window.
Definition: window_gui.h:157
virtual void LoadTextfile(const char *textfile, Subdirectory dir)
Loads the textfile text from file and setup lines.
SortButtonState
State of a sort direction button.
Definition: window_gui.h:224
static NWidgetPart NWidget(WidgetType tp, Colours col, int16 idx=-1)
Widget part function for starting a new &#39;real&#39; widget.
Definition: widget_type.h:1114
Offset at bottom to draw the frame rectangular area.
Definition: window_gui.h:65
static WindowDesc _network_content_download_status_window_desc(WDP_CENTER, NULL, 0, 0, WC_NETWORK_STATUS_WINDOW, WC_NONE, WDF_MODAL, _nested_network_content_download_status_window_widgets, lengthof(_nested_network_content_download_status_window_widgets))
Window description for the download window.
Baseclass for nested widgets.
Definition: widget_type.h:126
virtual void OnEditboxChanged(int wid)
The text in an editbox has been edited.
int DrawString(int left, int right, int top, const char *str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
Draw string, possibly truncated to make it fit in its allocated space.
Definition: gfx.cpp:499
SmallVector< ContentType, 4 > receivedTypes
Types we received so we can update their cache.
const ContentInfo * ci
View the textfile of this ContentInfo.
#define lengthof(x)
Return the length of an fixed size array.
Definition: depend.cpp:42
TextfileType
Additional text files accompanying Tar archives.
Definition: textfile_type.h:16
virtual void OnDownloadProgress(const ContentInfo *ci, int bytes)
We have progress in the download of a file.
Grid of rows and columns.
Definition: widget_type.h:59
static T min(const T a, const T b)
Returns the minimum of two values.
Definition: math_func.hpp:42
uint pos_x
Horizontal position of top-left corner of the widget in the window.
Definition: widget_type.h:177
void DrawMatrix(const Rect &r) const
Draw/fill the matrix with the list of content to download.
int cancel_button
Widget button of parent window to simulate when pressing CANCEL in OSK.
static int CDECL NameSorter(const ContentInfo *const *a, const ContentInfo *const *b)
Sort content by name.
void SetSortType(uint8 n_type)
Set the sorttype of the list.
bool Sort(SortFunction *compare)
Sort the list.
void BuildContentList()
(Re)build the network game list as its amount has changed because an item has been added or deleted f...
QueryString filter_editbox
Filter editbox;.
uint32 StringID
Numeric value that represents a string, independent of the selected language.
Definition: strings_type.h:18
void DeleteWindowByClass(WindowClass cls)
Delete all windows of a given class.
Definition: window.cpp:1150
&#39;Type&#39; button.
byte md5sum[16]
The MD5 checksum.
Definition: tcp_content.h:78
virtual void OnDownloadComplete(ContentID cid)
We have finished downloading a file.
uint total_bytes
Number of bytes to download.
The content consists of a GS library.
Definition: tcp_content.h:36
&#39;Select updates&#39; button.
void SortContentList()
Sort the content list.
Window for showing the download status of content.
bool auto_select
Automatically select all content when the meta-data becomes available.
The window is a modal child of some other window, meaning the parent is &#39;inactive&#39;.
Definition: window_gui.h:211
uint DoScan(Subdirectory sd)
Perform the scanning of a particular subdirectory.
Definition: fileio.cpp:646
void SetDirty() const
Mark entire window as dirty (in need of re-paint)
Definition: window.cpp:959
The content consists of a NewGRF.
Definition: tcp_content.h:28
Dimension GetStringBoundingBox(const char *str, FontSize start_fontsize)
Return the string dimension in pixels.
Definition: gfx.cpp:699
ContentType
The values in the enum are important; they are used as database &#39;keys&#39;.
Definition: tcp_content.h:25
Network status window; Window numbers:
Definition: window_type.h:487
void AddLine(const char *str)
Pass another text line from the current item to the filter.
virtual void OnInvalidateData(int data=0, bool gui_scope=true)
Some data on this window has become invalid.
void ForceResort()
Force a resort next Sort call Reset the resort timer if used too.
Dimension maxdim(const Dimension &d1, const Dimension &d2)
Compute bounding box of both dimensions.
No window, redirects to WC_MAIN_WINDOW.
Definition: window_type.h:40
void DeleteWindowById(WindowClass cls, WindowNumber number, bool force)
Delete a window by its class and window number (if it is open).
Definition: window.cpp:1137
NWID_SELECTION widget for select all/update buttons..
static const uint8 PC_GREY
Grey palette colour.
Definition: gfx_func.h:209
static const uint8 PC_DARK_BLUE
Dark blue palette colour.
Definition: gfx_func.h:226
The content consists of an AI library.
Definition: tcp_content.h:30
Mode
The mode of tar scanning.
Definition: fileio_func.h:99
User interface for downloading files.
virtual void DrawWidget(const Rect &r, int widget) const
Draw the contents of a nested widget.
char *const buf
buffer in which text is saved
Definition: textbuf_type.h:34
void FilterContentList()
Filter the content list.
void SelectAll()
Select everything we can select.
(Optional) Cancel/OK button.
char name[48]
The current name of the downloaded file.
ContentListFilterCriteria
Filter criterias for NetworkContentListWindow.
uint downloaded_files
Number of files downloaded.
Filter editbox.
Window caption (window title between closebox and stickybox)
Definition: widget_type.h:61
Window for displaying a textfile.
Definition: textfile_gui.h:23
int strnatcmp(const char *s1, const char *s2, bool ignore_garbage_at_front)
Compares two strings using case insensitive natural sort.
Definition: string.cpp:569
void RemoveCallback(ContentCallback *cb)
Remove a callback.
&#39;Select all&#39; button.
uint32 SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition: gfx_type.h:19
static bool StrEmpty(const char *s)
Check if a string buffer is empty.
Definition: string_func.h:59
void SetFilterState(bool state)
Enable or disable the filter.
uint total_files
Number of files to download.
The content consists of a heightmap.
Definition: tcp_content.h:32
The content consists of an AI.
Definition: tcp_content.h:29
const char * GetTextfile(TextfileType type) const
Search a textfile file next to this file in the content list.
void ToggleSortOrder()
Toggle the sort order Since that is the worst condition for the sort function reverse the list here...
ContentType type
Type of content.
Definition: tcp_content.h:69
bool upgrade
This item is an upgrade.
Definition: tcp_content.h:84
bool CDECL FilterFunction(const T *, F)
Signature of filter function.
Definition: sortlist_type.h:53
void ShowNetworkContentListWindow(ContentVector *cv, ContentType type1, ContentType type2)
Show the content list window with a given set of content.
Sort ascending.
Definition: window_gui.h:226
&#39;Open url&#39; button.
Button above checkboxes.
virtual void OnConnect(bool success)
Callback for when the connection has finished.
TextfileType file_type
Type of textfile to view.
Definition: textfile_gui.h:24
static void Rescan()
Rescans all searchpaths for available AIs.
Definition: ai_core.cpp:347
Vertical container.
Definition: widget_type.h:77
int CDECL SortFunction(const T *, const T *)
Signature of sort function.
Definition: sortlist_type.h:52
static NWidgetPart EndContainer()
Widget part function for denoting the end of a container (horizontal, vertical, WWT_FRAME, WWT_INSET, or WWT_PANEL).
Definition: widget_type.h:999
Network window; Window numbers:
Definition: window_type.h:468
char * strecpy(char *dst, const char *src, const char *last)
Copies characters from one buffer to another.
Definition: depend.cpp:68
static GUIContentList::FilterFunction *const filter_funcs[]
Filter functions.
uint current_x
Current horizontal size (after resizing).
Definition: widget_type.h:174
Helper to mark the begin of the types.
Definition: tcp_content.h:26
The content consists of base music.
Definition: tcp_content.h:34
Right offset of string.
Definition: window_gui.h:47
bool Include(const T &item)
Tests whether a item is present in the vector, and appends it to the end if not.
bool SetFocusedWidget(int widget_index)
Set focus within this window to the given widget.
Definition: window.cpp:484
void ScanNewGRFFiles(NewGRFScanCallback *callback)
Scan for all NewGRFs.
Coordinates of a point in 2D.
virtual EventState OnKeyPress(WChar key, uint16 keycode)
A key has been pressed.
Dimension GetSpriteSize(SpriteID sprid, Point *offset, ZoomLevel zoom)
Get the size of a sprite.
Definition: gfx.cpp:768
static Listing last_sorting
The last sorting setting.
virtual void OnClick(Point pt, int widget, int click_count)
A click with the left mouse button has been made on the window.
Data structure describing how to show the list (what sort direction and criteria).
Definition: sortlist_type.h:34
uint16 GetCapacity() const
Gets the number of visible elements of the scrollbar.
Definition: widget_type.h:622
Open readme, changelog (+1) or license (+2) of a file in the content window.
static char content_type_strs[CONTENT_TYPE_END][64]
Cached strings for all content types.
uint downloaded_bytes
Number of bytes downloaded.
static const StringID INVALID_STRING_ID
Constant representing an invalid string (16bit in case it is used in savegames)
Definition: strings_type.h:19
The content has been manually selected.
Definition: tcp_content.h:62
Offset at right to draw the frame rectangular area.
Definition: window_gui.h:63
void SetFiltering(Filtering f)
Import filter conditions.
The caption of the window.
Definition: misc_widget.h:50
static GUIContentList::SortFunction *const sorter_funcs[]
Sorter functions.
static NWidgetPart SetFill(uint fill_x, uint fill_y)
Widget part function for setting filling.
Definition: widget_type.h:983
const T * Get(uint index) const
Get the pointer to item "number" (const)
bool IsDescSortOrder() const
Check if the sort order is descending.
Caption for the filter editbox.
static Filtering last_filtering
The last filtering setting.
Network content list.
Definition: window_type.h:31
void SetCapacityFromWidget(Window *w, int widget, int padding=0)
Set capacity of visible elements from the size and resize properties of a widget. ...
Definition: widget.cpp:1973
Specification of a rectangle with absolute coordinates of all edges.
Vertical scrollbar.
Definition: widget_type.h:84
The passed event is handled.
Definition: window_type.h:702
Right align the text (must be a single bit).
Definition: gfx_func.h:100
BaseNetworkContentDownloadStatusWindow(WindowDesc *desc)
Create the window with the given description.
Scan nothing.
Definition: fileio_func.h:100
Filtering GetFiltering() const
Export current filter conditions.
Base window for showing the download status of content.
Filter by being of displayed type or selected for download.
uint32 cur_id
The current ID of the downloaded file.
Stacked widgets, only one visible at a time (eg in a panel with tabs).
Definition: widget_type.h:80
Subdirectory GetContentInfoSubDir(ContentType type)
Helper to get the subdirectory a ContentInfo is located in.
char url[96]
URL related to the content.
Definition: tcp_content.h:75
Errors (eg. saving/loading failed)
Definition: error.h:25
GUIList< const ContentInfo *, ContentListFilterData & > GUIContentList
List with content infos.
uint32 WChar
Type for wide characters, i.e.
Definition: string_type.h:35
void SetStringParameters(int widget) const
Initialize string parameters for a widget.
char description[512]
Description of the content.
Definition: tcp_content.h:76
bool IsWidgetFocused(byte widget_index) const
Check if given widget is focused within this window.
Definition: window_gui.h:427
static NWidgetPart SetScrollbar(int index)
Attach a scrollbar to a widget.
Definition: widget_type.h:1095
Dimensions (a width and height) of a rectangle in 2D.
Container for all important information about a piece of content.
Definition: tcp_content.h:58
Value of the NCB_EQUALSIZE flag.
Definition: widget_type.h:429
bool IsEmpty() const
Check whether any filter words were entered.
Offset at left to draw the frame rectangular area.
Definition: window_gui.h:62
void DrawDetails(const Rect &r) const
Helper function to draw the details part of this window.
Window * BringWindowToFrontById(WindowClass cls, WindowNumber number)
Find a window and make it the relative top-window on the screen.
Definition: window.cpp:1234
Game options window; Window numbers:
Definition: window_type.h:608
void OpenExternalSearch()
Search external websites for content.
void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub, ZoomLevel zoom)
Draw a sprite, not in a viewport.
Definition: gfx.cpp:833
static NWidgetPart SetPIP(uint8 pre, uint8 inter, uint8 post)
Widget part function for setting a pre/inter/post spaces.
Definition: widget_type.h:1076
Network content download status.
Definition: window_type.h:35
~NetworkContentListWindow()
Free everything we allocated.
ClientNetworkContentSocketHandler _network_content_client
The client we use to connect to the server.
void InvalidateData(int data=0, bool gui_scope=true)
Mark this window&#39;s data as invalid (in need of re-computing)
Definition: window.cpp:3161
void InvalidateWindowData(WindowClass cls, WindowNumber number, int data, bool gui_scope)
Mark window data of the window of a given class and specific window number as invalid (in need of re-...
Definition: window.cpp:3220
uint filesize_sum
The sum of all selected file sizes.
int DrawStringMultiLine(int left, int right, int top, int bottom, const char *str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
Draw string, possibly over multiple lines.
Definition: gfx.cpp:620
void ToggleSelectedState(const ContentInfo *ci)
Toggle the state of a content info and check its dependencies.
The content consists of base sounds.
Definition: tcp_content.h:33
Top offset of string.
Definition: window_gui.h:48
static int CDECL StateSorter(const ContentInfo *const *a, const ContentInfo *const *b)
Sort content by state.
uint8 SortType() const
Get the sorttype of the list.
Definition: sortlist_type.h:97
static void SetDParam(uint n, uint64 v)
Set a string parameter v at index n in the global string parameter array.
Definition: strings_func.h:201
virtual void OnDownloadProgress(const ContentInfo *ci, int bytes)
We have progress in the download of a file.