Index: industry_gui.cpp =================================================================== --- industry_gui.cpp (revision 11760) +++ industry_gui.cpp (working copy) @@ -636,14 +636,17 @@ enum IndustryDirectoryWidgets { IDW_CLOSEBOX = 0, IDW_CAPTION, IDW_STICKY, - IDW_SORTBYNAME, - IDW_SORTBYTYPE, - IDW_SORTBYPROD, - IDW_SORTBYTRANSPORT, - IDW_SPACER, + IDW_SORTBY, + IDW_SORTCRITERIA, + IDW_SORTDROPBTN, + IDW_PAN_BETWEEN, + IDW_NOCARGO, + IDW_CARGOALL, + IDW_PAN_RIGHT, IDW_INDUSRTY_LIST, IDW_SCROLLBAR, IDW_RESIZE, + IDW_CARGOSTART, }; /** Widget definition of the industy directory gui */ @@ -651,11 +654,13 @@ static const Widget _industry_directory_ { WWT_CLOSEBOX, RESIZE_NONE, 13, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, // IDW_CLOSEBOX { WWT_CAPTION, RESIZE_NONE, 13, 11, 495, 0, 13, STR_INDUSTRYDIR_CAPTION, STR_018C_WINDOW_TITLE_DRAG_THIS}, // IDW_CAPTION { WWT_STICKYBOX, RESIZE_NONE, 13, 496, 507, 0, 13, 0x0, STR_STICKY_BUTTON}, // IDW_STICKY -{ WWT_PUSHTXTBTN, RESIZE_NONE, 13, 0, 100, 14, 25, STR_SORT_BY_NAME, STR_SORT_ORDER_TIP}, // IDW_SORTBYNAME -{ WWT_PUSHTXTBTN, RESIZE_NONE, 13, 101, 200, 14, 25, STR_SORT_BY_TYPE, STR_SORT_ORDER_TIP}, // IDW_SORTBYTYPE -{ WWT_PUSHTXTBTN, RESIZE_NONE, 13, 201, 300, 14, 25, STR_SORT_BY_PRODUCTION, STR_SORT_ORDER_TIP}, // IDW_SORTBYPROD -{ WWT_PUSHTXTBTN, RESIZE_NONE, 13, 301, 400, 14, 25, STR_SORT_BY_TRANSPORTED, STR_SORT_ORDER_TIP}, // IDW_SORTBYTRANSPORT -{ WWT_PANEL, RESIZE_NONE, 13, 401, 495, 14, 25, 0x0, STR_NULL}, // IDW_SPACER +{ WWT_TEXTBTN, RESIZE_NONE, 13, 0, 80, 14, 25, STR_SORT_BY, STR_SORT_ORDER_TIP}, // IDW_SORTBY +{ WWT_PANEL, RESIZE_NONE, 13, 81, 232, 14, 25, 0x0, STR_SORT_CRITERIA_TIP}, // IDW_SORTCRITERIA +{ WWT_TEXTBTN, RESIZE_NONE, 13, 233, 243, 14, 25, STR_0225, STR_SORT_CRITERIA_TIP}, // IDW_SORTDROPBTN +{ WWT_PANEL, RESIZE_NONE, 13, 244, 249, 14, 25, 0x0, STR_NULL}, // IDW_PAN_BETWEEN +{ WWT_PANEL, RESIZE_NONE, 13, 250, 263, 14, 25, 0x0, STR_NO_WAITING_CARGO}, // IDW_NOCARGO +{ WWT_PANEL, RESIZE_NONE, 13, 264, 277, 14, 25, 0x0, STR_SELECT_ALL_TYPES}, // IDW_CARGOALL +{ WWT_PANEL, RESIZE_NONE, 13, 278, 507, 14, 25, 0x0, STR_NULL}, // IDW_PAN_RIGHT { WWT_PANEL, RESIZE_BOTTOM, 13, 0, 495, 26, 189, 0x0, STR_200A_TOWN_NAMES_CLICK_ON_NAME}, // IDW_INDUSRTY_LIST { WWT_SCROLLBAR, RESIZE_BOTTOM, 13, 496, 507, 14, 177, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST}, // IDW_SCROLLBAR { WWT_RESIZEBOX, RESIZE_TB, 13, 496, 507, 178, 189, 0x0, STR_RESIZE_BUTTON}, // IDW_RESIZE @@ -752,17 +757,33 @@ static int CDECL GeneralIndustrySorter(c * starts a new game without industries after playing a game with industries * the list is not populated with invalid industries from the previous game. */ -static void MakeSortedIndustryList() +static void MakeSortedIndustryList(uint32 cargo_filter, bool include_empty) { const Industry* i; int n = 0; - /* Create array for sorting */ - _industry_sort = ReallocT(_industry_sort, GetMaxIndustryIndex() + 1); + /* Create array for filtering */ + const Industry** industry_sort = MallocT(GetMaxIndustryIndex() +1); + + FOR_ALL_INDUSTRIES(i) { + if (i->produced_cargo[0] != 255 && HasBit(cargo_filter, i->produced_cargo[0])) { + industry_sort[n++] = i; continue; + } + if (i->produced_cargo[1] != 255 && HasBit(cargo_filter, i->produced_cargo[1])) { + industry_sort[n++] = i; continue; + } + /* stations without waiting cargo */ + if (i->produced_cargo[0] == 255 && i->produced_cargo[1] == 255 && include_empty) { + industry_sort[n++] = i; + } + } + + free((void*)_industry_sort); + _industry_sort = MallocT(n); + for (int j = 0; j < n; ++j) _industry_sort[j] = industry_sort[j]; /* Don't attempt a sort if there are no industries */ - if (GetNumIndustries() != 0) { - FOR_ALL_INDUSTRIES(i) _industry_sort[n++] = i; + if (n != 0) { qsort((void*)_industry_sort, n, sizeof(_industry_sort[0]), GeneralIndustrySorter); } @@ -772,24 +793,62 @@ static void MakeSortedIndustryList() DEBUG(misc, 3, "Resorting industries list"); } +static const uint32 _cargo_filter_max = ~0; +static uint32 _cargo_filter = _cargo_filter_max; +bool _include_empty = true; + +const StringID _industry_directory_sort_listing[] = { + STR_SORT_BY_DROPDOWN_NAME, + STR_SORT_BY_TYPE, + STR_SORT_BY_PRODUCTION, + STR_SORT_BY_TRANSPORTED, + INVALID_STRING_ID +}; static void IndustryDirectoryWndProc(Window *w, WindowEvent *e) { switch (e->event) { + case WE_CREATE: + w->SetWidgetLoweredState(IDW_NOCARGO, _include_empty); + w->SetWidgetLoweredState(IDW_CARGOALL, _cargo_filter == _cargo_mask && _include_empty); + break; case WE_PAINT: { int n; uint p; - static const uint16 _indicator_positions[4] = {88, 187, 284, 387}; if (_industry_sort_dirty) { _industry_sort_dirty = false; - MakeSortedIndustryList(); + MakeSortedIndustryList(_cargo_filter, _include_empty); } SetVScrollCount(w, _num_industry_sort); DrawWindowWidgets(w); - DoDrawString(_industry_sort_order & 1 ? DOWNARROW : UPARROW, _indicator_positions[_industry_sort_order >> 1], 15, TC_BLACK); + DoDrawString(_industry_sort_order & 1 ? DOWNARROW : UPARROW, 69, 15, TC_BLACK); + DrawString(85, 15, _industry_directory_sort_listing[_industry_sort_order >> 1], TC_BLACK); + + int cg_ofst; + int x = 250; + int y = 14; + + uint i = 0; + for (CargoID c = 0; c < NUM_CARGO; c++) { + const CargoSpec *cs = GetCargo(c); + if (!cs->IsValid()) continue; + + cg_ofst = HasBit(_cargo_filter, c) ? 2 : 1; + GfxFillRect(x + cg_ofst, y + cg_ofst, x + cg_ofst + 10 , y + cg_ofst + 7, cs->rating_colour); + DrawStringCentered(x + 6 + cg_ofst, y + cg_ofst, cs->abbrev, TC_BLACK); + x += 14; + i++; + } + + x += 6; + cg_ofst = w->IsWidgetLowered(IDW_NOCARGO) ? 2 : 1; + DrawStringCentered(x + cg_ofst, y + cg_ofst, STR_ABBREV_NONE, TC_BLACK); + x += 14; + cg_ofst = w->IsWidgetLowered(IDW_CARGOALL) ? 2 : 1; + DrawStringCentered(x + cg_ofst, y + cg_ofst, STR_ABBREV_ALL, TC_BLACK); p = w->vscroll.pos; n = 0; @@ -822,29 +881,21 @@ static void IndustryDirectoryWndProc(Win case WE_CLICK: switch (e->we.click.widget) { - case IDW_SORTBYNAME: { - _industry_sort_order = _industry_sort_order == 0 ? 1 : 0; - _industry_sort_dirty = true; - SetWindowDirty(w); - } break; - - case IDW_SORTBYTYPE: { - _industry_sort_order = _industry_sort_order == 2 ? 3 : 2; - _industry_sort_dirty = true; - SetWindowDirty(w); - } break; - - case IDW_SORTBYPROD: { - _industry_sort_order = _industry_sort_order == 4 ? 5 : 4; + case IDW_SORTBY: // flip sorting method asc/desc +/* sl->flags ^= SL_ORDER; //DESC-flag + station_sort.order = HasBit(sl->flags, 0); + sl->flags |= SL_RESORT; + w->flags4 |= 5 << WF_TIMEOUT_SHL; + w->LowerWidget(SLW_SORTBY);*/ + _industry_sort_order ^= 1; _industry_sort_dirty = true; SetWindowDirty(w); - } break; + break; - case IDW_SORTBYTRANSPORT: { - _industry_sort_order = _industry_sort_order == 6 ? 7 : 6; - _industry_sort_dirty = true; - SetWindowDirty(w); - } break; + case IDW_SORTCRITERIA: + case IDW_SORTDROPBTN: // select sorting criteria dropdown menu + ShowDropDownMenu(w, _industry_directory_sort_listing, _industry_sort_order >> 1, IDW_SORTDROPBTN, 0, 0); + break; case IDW_INDUSRTY_LIST: { int y = (e->we.click.pt.y - 28) / 10; @@ -856,6 +907,72 @@ static void IndustryDirectoryWndProc(Win ScrollMainWindowToTile(_industry_sort[p]->xy); } } break; + case IDW_NOCARGO: + if (_ctrl_pressed) { + _include_empty = !_include_empty; + w->ToggleWidgetLoweredState(IDW_NOCARGO); + } else { + for (uint i = IDW_CARGOSTART; i < w->widget_count; i++) { + w->RaiseWidget(i); + } + + _cargo_filter = 0; + _include_empty = true; + + w->LowerWidget(IDW_NOCARGO); + } + w->SetWidgetLoweredState(IDW_CARGOALL, _cargo_filter == _cargo_mask && _include_empty); + _industry_sort_dirty = true; + SetWindowDirty(w); + break; + case IDW_CARGOALL: { + uint i = 0; + for (CargoID c = 0; c < NUM_CARGO; c++) { + if (!GetCargo(c)->IsValid()) continue; + w->LowerWidget(i + IDW_CARGOSTART); + i++; + } + w->LowerWidget(IDW_NOCARGO); + w->LowerWidget(IDW_CARGOALL); + + _cargo_filter = _cargo_mask; + _include_empty = true; + _industry_sort_dirty = true; + w->SetWidgetLoweredState(IDW_CARGOALL, _cargo_filter == _cargo_mask && _include_empty); + SetWindowDirty(w); + } + break; + default: + if (e->we.click.widget >= IDW_CARGOSTART) { // change cargo_filter + /* Determine the selected cargo type */ + CargoID c; + int i = 0; + for (c = 0; c < NUM_CARGO; c++) { + if (!GetCargo(c)->IsValid()) continue; + if (e->we.click.widget - IDW_CARGOSTART == i) break; + i++; + } + + if (_ctrl_pressed) { + ToggleBit(_cargo_filter, c); + w->ToggleWidgetLoweredState(e->we.click.widget); + } else { + for (uint i = IDW_CARGOSTART; i < w->widget_count; i++) { + w->RaiseWidget(i); + } + w->RaiseWidget(IDW_NOCARGO); + + _cargo_filter = 0; + _include_empty = false; + + SetBit(_cargo_filter, c); + w->LowerWidget(e->we.click.widget); + } + _industry_sort_dirty = true; + w->SetWidgetLoweredState(IDW_CARGOALL, _cargo_filter == _cargo_mask && _include_empty); + SetWindowDirty(w); + } + break; } break; @@ -863,6 +980,16 @@ static void IndustryDirectoryWndProc(Win SetWindowDirty(w); break; + case WE_DROPDOWN_SELECT: // we have selected a dropdown item in the list + if ((_industry_sort_order << 1) != e->we.dropdown.index) { + /* value has changed -> resort */ + CLRBITS(_industry_sort_order, 0x06); //b0110 + SETBITS(_industry_sort_order, e->we.dropdown.index << 1); + _industry_sort_dirty = true; + } + SetWindowDirty(w); + break; + case WE_RESIZE: w->vscroll.cap += e->we.sizing.diff.y / 10; break; @@ -881,6 +1008,50 @@ static const WindowDesc _industry_direct void ShowIndustryDirectory() { Window *w = AllocateWindowDescFront(&_industry_directory_desc, 0); + if (w == NULL) return; + + _cargo_filter = _cargo_mask; + + /* Add cargo filter buttons */ + uint num_active = 0; + for (CargoID c = 0; c < NUM_CARGO; c++) { + if (GetCargo(c)->IsValid()) num_active++; + } + + w->widget_count += num_active; + w->widget = ReallocT(w->widget, w->widget_count + 1); + w->widget[w->widget_count].type = WWT_LAST; + + uint i = 0; + for (CargoID c = 0; c < NUM_CARGO; c++) { + if (!GetCargo(c)->IsValid()) continue; + + Widget *wi = &w->widget[IDW_CARGOSTART + i]; + wi->type = WWT_PANEL; + wi->display_flags = RESIZE_NONE; + wi->color = 13; + wi->left = 250 + i * 14; + wi->right = wi->left + 13; + wi->top = 14; + wi->bottom = 25; + wi->data = 0; + wi->tooltips = STR_USE_CTRL_TO_SELECT_MORE; + + if (HasBit(_cargo_filter, c)) w->LowerWidget(IDW_CARGOSTART + i); + i++; + } + + w->widget[IDW_NOCARGO].left += num_active * 14; + w->widget[IDW_NOCARGO].right += num_active * 14; + w->widget[IDW_CARGOALL].left += num_active * 14; + w->widget[IDW_CARGOALL].right += num_active * 14; + w->widget[IDW_PAN_RIGHT].left += num_active * 14; + + if (num_active > 15) { + /* Resize and fix the minimum width, if necessary */ + ResizeWindow(w, (num_active - 15) * 14, 0); + w->resize.width = w->width; + } if (w != NULL) { w->vscroll.cap = 16;