2 * This file is part of OpenTTD.
3 * 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.
4 * 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.
5 * 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 /** @file subsidy_gui.cpp GUI for subsidies. */
13 #include "window_gui.h"
14 #include "strings_func.h"
15 #include "date_func.h"
16 #include "viewport_func.h"
18 #include "subsidy_func.h"
19 #include "subsidy_base.h"
20 #include "core/geometry_func.hpp"
22 #include "widgets/subsidy_widget.h"
24 #include "table/strings.h"
26 #include "safeguards.h"
28 struct SubsidyListWindow
: Window
{
31 SubsidyListWindow(WindowDesc
*desc
, WindowNumber window_number
) : Window(desc
)
33 this->CreateNestedTree();
34 this->vscroll
= this->GetScrollbar(WID_SUL_SCROLLBAR
);
35 this->FinishInitNested(window_number
);
36 this->OnInvalidateData(0);
39 void OnClick(Point pt
, int widget
, int click_count
) override
41 if (widget
!= WID_SUL_PANEL
) return;
43 int y
= this->vscroll
->GetScrolledRowFromWidget(pt
.y
, this, WID_SUL_PANEL
, WD_FRAMERECT_TOP
);
45 for (const Subsidy
*s
: Subsidy::Iterate()) {
46 if (!s
->IsAwarded()) {
61 y
-= 2; // "Services already subsidised:"
64 for (const Subsidy
*s
: Subsidy::Iterate()) {
75 void HandleClick(const Subsidy
*s
)
77 /* determine src coordinate for subsidy and try to scroll to it */
79 switch (s
->src_type
) {
80 case ST_INDUSTRY
: xy
= Industry::Get(s
->src
)->location
.tile
; break;
81 case ST_TOWN
: xy
= Town::Get(s
->src
)->xy
; break;
82 default: NOT_REACHED();
85 if (_ctrl_pressed
|| !ScrollMainWindowToTile(xy
)) {
86 if (_ctrl_pressed
) ShowExtraViewportWindow(xy
);
88 /* otherwise determine dst coordinate for subsidy and scroll to it */
89 switch (s
->dst_type
) {
90 case ST_INDUSTRY
: xy
= Industry::Get(s
->dst
)->location
.tile
; break;
91 case ST_TOWN
: xy
= Town::Get(s
->dst
)->xy
; break;
92 default: NOT_REACHED();
96 ShowExtraViewportWindow(xy
);
98 ScrollMainWindowToTile(xy
);
104 * Count the number of lines in this window.
105 * @return the number of lines
109 /* Count number of (non) awarded subsidies */
110 uint num_awarded
= 0;
111 uint num_not_awarded
= 0;
112 for (const Subsidy
*s
: Subsidy::Iterate()) {
113 if (!s
->IsAwarded()) {
120 /* Count the 'none' lines */
121 if (num_awarded
== 0) num_awarded
= 1;
122 if (num_not_awarded
== 0) num_not_awarded
= 1;
124 /* Offered, accepted and an empty line before the accepted ones. */
125 return 3 + num_awarded
+ num_not_awarded
;
128 void UpdateWidgetSize(int widget
, Dimension
*size
, const Dimension
&padding
, Dimension
*fill
, Dimension
*resize
) override
130 if (widget
!= WID_SUL_PANEL
) return;
131 Dimension d
= maxdim(GetStringBoundingBox(STR_SUBSIDIES_OFFERED_TITLE
), GetStringBoundingBox(STR_SUBSIDIES_SUBSIDISED_TITLE
));
133 resize
->height
= d
.height
;
136 d
.width
+= padding
.width
+ WD_FRAMERECT_RIGHT
+ WD_FRAMERECT_LEFT
;
137 d
.height
+= padding
.height
+ WD_FRAMERECT_TOP
+ WD_FRAMERECT_BOTTOM
;
138 *size
= maxdim(*size
, d
);
141 void DrawWidget(const Rect
&r
, int widget
) const override
143 if (widget
!= WID_SUL_PANEL
) return;
146 ConvertDateToYMD(_date
, &ymd
);
148 int right
= r
.right
- WD_FRAMERECT_RIGHT
;
149 int y
= r
.top
+ WD_FRAMERECT_TOP
;
150 int x
= r
.left
+ WD_FRAMERECT_LEFT
;
152 int pos
= -this->vscroll
->GetPosition();
153 const int cap
= this->vscroll
->GetCapacity();
155 /* Section for drawing the offered subsidies */
156 if (IsInsideMM(pos
, 0, cap
)) DrawString(x
, right
, y
+ pos
* FONT_HEIGHT_NORMAL
, STR_SUBSIDIES_OFFERED_TITLE
);
160 for (const Subsidy
*s
: Subsidy::Iterate()) {
161 if (!s
->IsAwarded()) {
162 if (IsInsideMM(pos
, 0, cap
)) {
163 /* Displays the two offered towns */
164 SetupSubsidyDecodeParam(s
, true);
165 SetDParam(7, _date
- ymd
.day
+ s
->remaining
* 32);
166 DrawString(x
, right
, y
+ pos
* FONT_HEIGHT_NORMAL
, STR_SUBSIDIES_OFFERED_FROM_TO
);
174 if (IsInsideMM(pos
, 0, cap
)) DrawString(x
, right
, y
+ pos
* FONT_HEIGHT_NORMAL
, STR_SUBSIDIES_NONE
);
178 /* Section for drawing the already granted subsidies */
180 if (IsInsideMM(pos
, 0, cap
)) DrawString(x
, right
, y
+ pos
* FONT_HEIGHT_NORMAL
, STR_SUBSIDIES_SUBSIDISED_TITLE
);
184 for (const Subsidy
*s
: Subsidy::Iterate()) {
185 if (s
->IsAwarded()) {
186 if (IsInsideMM(pos
, 0, cap
)) {
187 SetupSubsidyDecodeParam(s
, true);
188 SetDParam(7, s
->awarded
);
189 SetDParam(8, _date
- ymd
.day
+ s
->remaining
* 32);
191 /* Displays the two connected stations */
192 DrawString(x
, right
, y
+ pos
* FONT_HEIGHT_NORMAL
, STR_SUBSIDIES_SUBSIDISED_FROM_TO
);
200 if (IsInsideMM(pos
, 0, cap
)) DrawString(x
, right
, y
+ pos
* FONT_HEIGHT_NORMAL
, STR_SUBSIDIES_NONE
);
205 void OnResize() override
207 this->vscroll
->SetCapacityFromWidget(this, WID_SUL_PANEL
);
211 * Some data on this window has become invalid.
212 * @param data Information about the changed data.
213 * @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details.
215 void OnInvalidateData(int data
= 0, bool gui_scope
= true) override
217 if (!gui_scope
) return;
218 this->vscroll
->SetCount(this->CountLines());
222 static const NWidgetPart _nested_subsidies_list_widgets
[] = {
223 NWidget(NWID_HORIZONTAL
),
224 NWidget(WWT_CLOSEBOX
, COLOUR_BROWN
),
225 NWidget(WWT_CAPTION
, COLOUR_BROWN
), SetDataTip(STR_SUBSIDIES_CAPTION
, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS
),
226 NWidget(WWT_SHADEBOX
, COLOUR_BROWN
),
227 NWidget(WWT_DEFSIZEBOX
, COLOUR_BROWN
),
228 NWidget(WWT_STICKYBOX
, COLOUR_BROWN
),
230 NWidget(NWID_HORIZONTAL
),
231 NWidget(WWT_PANEL
, COLOUR_BROWN
, WID_SUL_PANEL
), SetDataTip(0x0, STR_SUBSIDIES_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER
), SetResize(1, 1), SetScrollbar(WID_SUL_SCROLLBAR
), EndContainer(),
232 NWidget(NWID_VERTICAL
),
233 NWidget(NWID_VSCROLLBAR
, COLOUR_BROWN
, WID_SUL_SCROLLBAR
),
234 NWidget(WWT_RESIZEBOX
, COLOUR_BROWN
),
239 static WindowDesc
_subsidies_list_desc(
240 WDP_AUTO
, "list_subsidies", 500, 127,
241 WC_SUBSIDIES_LIST
, WC_NONE
,
243 _nested_subsidies_list_widgets
, lengthof(_nested_subsidies_list_widgets
)
247 void ShowSubsidiesList()
249 AllocateWindowDescFront
<SubsidyListWindow
>(&_subsidies_list_desc
, 0);