Files
openttd-cmclient/src/zoning_gui.cpp
2020-05-19 18:38:29 +03:00

201 lines
6.1 KiB
C++

/** @file zoning_gui.cpp */
#include "stdafx.h"
#include "widgets/dropdown_func.h"
#include "table/strings.h"
#include "strings_func.h"
#include "gfx_func.h"
#include "core/geometry_func.hpp"
#include "zoning.h"
#include "hotkeys.h"
const StringID _zone_types[] = {
//STR_ZONING_NO_ZONING,
STR_ZONING_AUTHORITY,
STR_ZONING_CAN_BUILD,
STR_ZONING_STA_CATCH,
STR_ZONING_ACTIVE_STATIONS,
STR_ZONING_BUL_UNSER,
STR_ZONING_IND_UNSER,
STR_ZONING_TOWN_ZONES,
STR_ZONING_CB_ACCEPTANCE,
STR_ZONING_CB_TOWN_LIMIT,
STR_ZONING_ADVERTISEMENT_ZONES,
STR_ZONING_TOWN_GROWTH_TILES,
};
const int ZONES_COUNT = 11;
enum ZoningToolbarWidgets {
ZTW_CAPTION,
ZTW_OUTER_FIRST,
ZTW_INNER_FIRST = ZTW_OUTER_FIRST + ZONES_COUNT,
ZTW_INNER_END = ZTW_INNER_FIRST + ZONES_COUNT,
};
struct ZoningWindow : public Window {
uint maxwidth;
uint maxheight;
ZoningWindow(WindowDesc *desc, int window_number) : Window(desc) {
Dimension dim;
this->maxwidth = 0;
this->maxheight = 0;
for (int i = 0; i < ZONES_COUNT; i++) {
dim = GetStringBoundingBox(_zone_types[i]);
this->maxwidth = max(this->maxwidth, dim.width);
this->maxheight = max(this->maxheight, dim.height);
}
this->InitNested(window_number);
this->InvalidateData();
if(_zoning.outer != CHECKNOTHING) this->LowerWidget(ZTW_OUTER_FIRST + _zoning.outer - 1); //-1:skip CHECKNOTHING
if(_zoning.inner != CHECKNOTHING) this->LowerWidget(ZTW_INNER_FIRST + _zoning.inner - 1);
}
virtual void OnPaint() {
this->DrawWidgets();
}
virtual void OnClick(Point pt, int widget, int click_count) {
bool outer = true;
bool deselect = false;
EvaluationMode clicked;
if (widget >= ZTW_OUTER_FIRST && widget < ZTW_INNER_FIRST){
clicked = (EvaluationMode)(widget - ZTW_OUTER_FIRST + 1); //+1:skip CHECKNOTHING
deselect = _zoning.outer == clicked;
_zoning.outer = deselect ? CHECKNOTHING : clicked;
}
else if (widget >= ZTW_INNER_FIRST && widget < ZTW_INNER_END){
clicked = (EvaluationMode)(widget - ZTW_INNER_FIRST + 1);
deselect = _zoning.inner == clicked;
_zoning.inner = deselect ? CHECKNOTHING : clicked;
outer = false;
}
else return;
this->RaiseAllWidgets(outer);
if(!deselect) this->ToggleWidgetLoweredState(widget);
this->InvalidateData();
MarkWholeScreenDirty();
}
void DrawWidget(const Rect &r, int widget) const
{
StringID strid = STR_EMPTY;
if (widget >= ZTW_OUTER_FIRST && widget < ZTW_INNER_FIRST){
strid = _zone_types[widget - ZTW_OUTER_FIRST];
}
else if (widget >= ZTW_INNER_FIRST && widget < ZTW_INNER_END){
strid = _zone_types[widget - ZTW_INNER_FIRST];
}
else return;
bool rtl = _current_text_dir == TD_RTL;
byte clk_dif = this->IsWidgetLowered(widget) ? 1 : 0;
int x = r.left + WD_FRAMERECT_LEFT;
int y = r.top;
DrawString(rtl ? r.left : x + clk_dif + 1, (rtl ? r.right + clk_dif : r.right), y + 1 + clk_dif, strid, TC_FROMSTRING, SA_LEFT);
}
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) {
if (widget >= ZTW_OUTER_FIRST && widget < ZTW_INNER_END){
size->width = this->maxwidth + padding.width + 8;
size->height = this->maxheight + 2;
}
}
void RaiseAllWidgets(bool outer){
byte start = outer ? ZTW_OUTER_FIRST : ZTW_INNER_FIRST;
byte end = outer ? ZTW_INNER_FIRST : ZTW_INNER_END;
for(byte i = start; i < end; i++){
if(this->IsWidgetLowered(i)){
this->ToggleWidgetLoweredState(i);
break;
}
}
}
virtual EventState OnHotkey(int hotkey)
{
return Window::OnHotkey(hotkey);
}
static HotkeyList hotkeys;
};
static EventState ZoningWindowGlobalHotkeys(int hotkey) {
EvaluationMode zoning = (EvaluationMode)(hotkey - ZTW_OUTER_FIRST); // +1:skip CHECKNOTHING
bool deselect = (_zoning.outer == zoning);
_zoning.outer = deselect ? CHECKNOTHING : zoning;
MarkWholeScreenDirty();
return ES_HANDLED;
}
static Hotkey zoning_hotkeys[] = {
Hotkey(WKC_SHIFT | '1', "authority", ZTW_OUTER_FIRST + CHECKOPINION),
Hotkey(WKC_SHIFT | '2', "build_status", ZTW_OUTER_FIRST + CHECKBUILD),
Hotkey(WKC_SHIFT | '3', "station_catchment", ZTW_OUTER_FIRST + CHECKSTACATCH),
Hotkey(WKC_SHIFT | '4', "unserved_buildings", ZTW_OUTER_FIRST + CHECKBULUNSER),
Hotkey(WKC_SHIFT | '5', "unserved_industries", ZTW_OUTER_FIRST + CHECKINDUNSER),
Hotkey(WKC_SHIFT | '6', "town_zone", ZTW_OUTER_FIRST + CHECKTOWNZONES),
Hotkey(WKC_SHIFT | '7', "cb_acceptance", ZTW_OUTER_FIRST + CHECKCBACCEPTANCE),
Hotkey(WKC_SHIFT | '8', "cb_town_limit", ZTW_OUTER_FIRST + CHECKCBTOWNLIMIT),
Hotkey(WKC_SHIFT | '9', "advertisement", ZTW_OUTER_FIRST + CHECKTOWNADZONES),
Hotkey(WKC_SHIFT | '0', "growth_tiles", ZTW_OUTER_FIRST + CHECKTOWNGROWTHTILES),
Hotkey((uint16)0, "active_stations", ZTW_OUTER_FIRST + CHECKACTIVESTATIONS),
HOTKEY_LIST_END
};
HotkeyList ZoningWindow::hotkeys("zoning_gui", zoning_hotkeys, ZoningWindowGlobalHotkeys);
/** Construct the row containing the digit keys. */
static NWidgetBase *MakeZoningButtons(int *biggest_index)
{
NWidgetHorizontal *hor = new NWidgetHorizontal(NC_EQUALSIZE);
int zone_types_size = lengthof(_zone_types);
hor->SetPadding(1, 1, 1, 1);
for(int i = 0; i < 2; i++){
NWidgetVertical *ver = new NWidgetVertical;
int offset = (i == 0) ? ZTW_OUTER_FIRST : ZTW_INNER_FIRST;
for (int j = 0; j < zone_types_size; j++) {
NWidgetBackground *leaf = new NWidgetBackground(WWT_PANEL, i==0 ? COLOUR_ORANGE : COLOUR_YELLOW, offset + j, NULL);
leaf->SetFill(1, 0);
leaf->SetPadding(0, 0, 0, 0);
ver->Add(leaf);
}
hor->Add(ver);
}
*biggest_index = ZTW_INNER_END - 1;
return hor;
}
static const NWidgetPart _nested_zoning_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
NWidget(WWT_CAPTION, COLOUR_GREY, ZTW_CAPTION), SetDataTip(STR_ZONING_TOOLBAR, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
NWidget(WWT_SHADEBOX, COLOUR_GREY),
NWidget(WWT_STICKYBOX, COLOUR_GREY),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY),
NWidgetFunction(MakeZoningButtons),
EndContainer()
};
static WindowDesc _zoning_desc (
WDP_AUTO, NULL, 0, 0,
WC_ZONING_TOOLBAR, WC_NONE,
0,
_nested_zoning_widgets, lengthof(_nested_zoning_widgets),
&ZoningWindow::hotkeys
);
void ShowZoningToolbar() {
AllocateWindowDescFront<ZoningWindow>(&_zoning_desc, 0);
}