12 #include "../stdafx.h" 13 #include "../window_gui.h" 14 #include "../window_func.h" 15 #include "../company_base.h" 16 #include "../company_gui.h" 17 #include "../date_func.h" 18 #include "../viewport_func.h" 19 #include "../smallmap_gui.h" 20 #include "../core/geometry_func.hpp" 21 #include "../widgets/link_graph_legend_widget.h" 23 #include "table/strings.h" 25 #include "../safeguards.h" 32 0x0f, 0xd1, 0xd0, 0x57,
33 0x55, 0x53, 0xbf, 0xbd,
34 0xba, 0xb9, 0xb7, 0xb5
44 dpi->left = dpi->top = 0;
62 FOR_ALL_STATIONS(sta) {
63 if (sta->
rect.IsEmpty())
continue;
67 StationID from = sta->
index;
80 StationID to = lg[i->first].Station();
90 if (stb->
rect.IsEmpty())
continue;
113 return pt.x > dpi->left - padding && pt.y > dpi->top - padding &&
114 pt.x < dpi->left + dpi->width + padding &&
115 pt.y < dpi->top + dpi->height + padding;
128 const int left = dpi->left - padding;
129 const int right = dpi->left + dpi->width + padding;
130 const int top = dpi->top - padding;
131 const int bottom = dpi->top + dpi->height + padding;
138 const uint8 INSIDE = 0;
139 const uint8 LEFT = 1;
140 const uint8 RIGHT = 2;
141 const uint8 BOTTOM = 4;
149 auto out_code = [&](
int x,
int y) -> uint8 {
153 }
else if (x > right) {
158 }
else if (y > bottom) {
164 uint8 c0 = out_code(x0, y0);
165 uint8 c1 = out_code(x1, y1);
168 if (c0 == 0 || c1 == 0)
return true;
169 if ((c0 & c1) != 0)
return false;
172 x0 = x0 + (int)(((int64) (x1 - x0)) * ((int64) (top - y0)) / ((int64) (y1 - y0)));
174 }
else if (c0 & BOTTOM) {
175 x0 = x0 + (int)(((int64) (x1 - x0)) * ((int64) (bottom - y0)) / ((int64) (y1 - y0)));
177 }
else if (c0 & RIGHT) {
178 y0 = y0 + (int)(((int64) (y1 - y0)) * ((int64) (right - x0)) / ((int64) (x1 - x0)));
180 }
else if (c0 & LEFT) {
181 y0 = y0 + (int)(((int64) (y1 - y0)) * ((int64) (left - x0)) / ((int64) (x1 - x0)));
185 c0 = out_code(x0, y0);
232 cargo.
usage = new_usg;
235 if (new_shared) cargo.
shared =
true;
257 for (StationLinkMap::const_iterator j(i->second.begin()); j != i->second.end(); ++j) {
281 if (
abs(pta.x - ptb.x) <
abs(pta.y - ptb.y)) {
282 int offset_x = (pta.y > ptb.y ? 1 : -1) * side * this->
scale;
283 GfxDrawLine(pta.x + offset_x, pta.y, ptb.x + offset_x, ptb.y, colour, this->scale, dash);
285 int offset_y = (pta.x < ptb.x ? 1 : -1) * side * this->
scale;
286 GfxDrawLine(pta.x, pta.y + offset_y, ptb.x, ptb.y + offset_y, colour, this->scale, dash);
289 GfxDrawLine(pta.x, pta.y, ptb.x, ptb.y,
_colour_gradient[COLOUR_GREY][1], this->scale);
300 if (st == NULL)
continue;
304 uint r = this->
scale * 2 + this->
scale * 2 *
min(200, i->second) / 200;
325 int w2 = size / 2 + size % 2;
327 GfxFillRect(x - w1, y - w1, x + w2, y + w2, colour);
331 GfxDrawLine(x - w1, y - w1, x + w2, y - w1, border_colour);
332 GfxDrawLine(x - w1, y + w2, x + w2, y + w2, border_colour);
333 GfxDrawLine(x - w1, y - w1, x - w1, y + w2, border_colour);
334 GfxDrawLine(x + w2, y - w1, x + w2, y + w2, border_colour);
377 return MakeCompanyButtonRows(biggest_index, WID_LGL_COMPANY_FIRST, WID_LGL_COMPANY_LAST, 3, STR_NULL);
380 NWidgetBase *MakeSaturationLegendLinkGraphGUI(
int *biggest_index)
390 *biggest_index = WID_LGL_SATURATION_LAST;
394 NWidgetBase *MakeCargoesLegendLinkGraphGUI(
int *biggest_index)
400 if (i % ENTRIES_PER_ROW == 0) {
401 if (row) panel->
Add(row);
411 for (uint i = 0; i < 4 - (NUM_CARGO - 1) % 5; ++i) {
418 *biggest_index = WID_LGL_CARGO_LAST;
423 static const NWidgetPart _nested_linkgraph_legend_widgets[] = {
456 assert_compile(WID_LGL_SATURATION_LAST - WID_LGL_SATURATION_FIRST ==
460 WDP_AUTO,
"toolbar_linkgraph", 0, 0,
463 _nested_linkgraph_legend_widgets,
lengthof(_nested_linkgraph_legend_widgets)
471 AllocateWindowDescFront<LinkGraphLegendWindow>(&_linkgraph_legend_desc, 0);
474 LinkGraphLegendWindow::LinkGraphLegendWindow(
WindowDesc *desc,
int window_number) :
Window(desc)
476 this->InitNested(window_number);
477 this->InvalidateData(0);
486 this->overlay = overlay;
489 if (!this->IsWidgetDisabled(WID_LGL_COMPANY_FIRST + c)) {
490 this->SetWidgetLoweredState(WID_LGL_COMPANY_FIRST + c,
HasBit(companies, c));
495 if (!this->IsWidgetDisabled(WID_LGL_CARGO_FIRST + c)) {
496 this->SetWidgetLoweredState(WID_LGL_CARGO_FIRST + c,
HasBit(cargoes, c));
503 if (
IsInsideMM(widget, WID_LGL_SATURATION_FIRST, WID_LGL_SATURATION_LAST + 1)) {
505 if (widget == WID_LGL_SATURATION_FIRST) {
506 str = STR_LINKGRAPH_LEGEND_UNUSED;
507 }
else if (widget == WID_LGL_SATURATION_LAST) {
508 str = STR_LINKGRAPH_LEGEND_OVERLOADED;
509 }
else if (widget == (WID_LGL_SATURATION_LAST + WID_LGL_SATURATION_FIRST) / 2) {
510 str = STR_LINKGRAPH_LEGEND_SATURATED;
512 if (str != STR_NULL) {
516 *size =
maxdim(*size, dim);
519 if (
IsInsideMM(widget, WID_LGL_CARGO_FIRST, WID_LGL_CARGO_LAST + 1)) {
525 *size =
maxdim(*size, dim);
532 if (
IsInsideMM(widget, WID_LGL_COMPANY_FIRST, WID_LGL_COMPANY_LAST + 1)) {
533 if (this->IsWidgetDisabled(widget))
return;
536 DrawCompanyIcon(cid, (r.left + r.right + 1 - sprite_size.width) / 2, (r.top + r.bottom + 1 - sprite_size.height) / 2);
538 if (
IsInsideMM(widget, WID_LGL_SATURATION_FIRST, WID_LGL_SATURATION_LAST + 1)) {
541 if (widget == WID_LGL_SATURATION_FIRST) {
542 str = STR_LINKGRAPH_LEGEND_UNUSED;
543 }
else if (widget == WID_LGL_SATURATION_LAST) {
544 str = STR_LINKGRAPH_LEGEND_OVERLOADED;
545 }
else if (widget == (WID_LGL_SATURATION_LAST + WID_LGL_SATURATION_FIRST) / 2) {
546 str = STR_LINKGRAPH_LEGEND_SATURATED;
550 if (
IsInsideMM(widget, WID_LGL_CARGO_FIRST, WID_LGL_CARGO_LAST + 1)) {
551 if (this->IsWidgetDisabled(widget))
return;
553 GfxFillRect(r.left + 2, r.top + 2, r.right - 2, r.bottom - 2, cargo->legend_colour);
558 bool LinkGraphLegendWindow::OnHoverCommon(
Point pt,
int widget, TooltipCloseCondition close_cond)
560 if (
IsInsideMM(widget, WID_LGL_COMPANY_FIRST, WID_LGL_COMPANY_LAST + 1)) {
561 if (this->IsWidgetDisabled(widget)) {
562 GuiShowTooltips(
this, STR_LINKGRAPH_LEGEND_SELECT_COMPANIES, 0, NULL, close_cond);
566 params[0] = STR_LINKGRAPH_LEGEND_SELECT_COMPANIES;
568 GuiShowTooltips(
this, STR_LINKGRAPH_LEGEND_COMPANY_TOOLTIP, 2, params, close_cond);
572 if (
IsInsideMM(widget, WID_LGL_CARGO_FIRST, WID_LGL_CARGO_LAST + 1)) {
573 if (this->IsWidgetDisabled(widget))
return false;
576 params[0] = cargo->
name;
585 this->OnHoverCommon(pt, widget, TCC_HOVER);
591 return this->OnHoverCommon(pt, widget, TCC_RIGHT_CLICK);
603 if (this->IsWidgetDisabled(c + WID_LGL_COMPANY_FIRST))
continue;
604 if (!this->IsWidgetLowered(c + WID_LGL_COMPANY_FIRST))
continue;
607 this->overlay->SetCompanyMask(mask);
617 if (this->IsWidgetDisabled(c + WID_LGL_CARGO_FIRST))
continue;
618 if (!this->IsWidgetLowered(c + WID_LGL_CARGO_FIRST))
continue;
621 this->overlay->SetCargoMask(mask);
627 if (
IsInsideMM(widget, WID_LGL_COMPANY_FIRST, WID_LGL_COMPANY_LAST + 1)) {
628 if (!this->IsWidgetDisabled(widget)) {
629 this->ToggleWidgetLoweredState(widget);
630 this->UpdateOverlayCompanies();
632 }
else if (widget == WID_LGL_COMPANIES_ALL || widget == WID_LGL_COMPANIES_NONE) {
634 if (this->IsWidgetDisabled(c + WID_LGL_COMPANY_FIRST))
continue;
635 this->SetWidgetLoweredState(WID_LGL_COMPANY_FIRST + c, widget == WID_LGL_COMPANIES_ALL);
637 this->UpdateOverlayCompanies();
639 }
else if (
IsInsideMM(widget, WID_LGL_CARGO_FIRST, WID_LGL_CARGO_LAST + 1)) {
640 if (!this->IsWidgetDisabled(widget)) {
641 this->ToggleWidgetLoweredState(widget);
642 this->UpdateOverlayCargoes();
644 }
else if (widget == WID_LGL_CARGOES_ALL || widget == WID_LGL_CARGOES_NONE) {
646 if (this->IsWidgetDisabled(c + WID_LGL_CARGO_FIRST))
continue;
647 this->SetWidgetLoweredState(WID_LGL_CARGO_FIRST + c, widget == WID_LGL_CARGOES_ALL);
649 this->UpdateOverlayCargoes();
666 this->SetWidgetDisabledState(i + WID_LGL_CARGO_FIRST, !
CargoSpec::Get(i)->IsValid());
VehicleSettings vehicle
options for vehicles
Properties of a link between two stations.
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Data about how and where to blit pixels.
Horizontally center the text.
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...
virtual void OnHover(Point pt, int widget)
The mouse is hovering over a widget in the window, perform an action for it, like opening a custom to...
void SetOverlay(LinkGraphOverlay *overlay)
Set the overlay belonging to this menu and import its company/cargo settings.
LinkMap cached_links
Cache for links to reduce recalculation.
uint32 GetCompanyMask()
Get a bitmask of the currently shown companies.
High level window description.
virtual void OnClick(Point pt, int widget, int click_count)
A click with the left mouse button has been made on the window.
uint usage
Actual usage of the link.
static Titem * Get(size_t index)
Returns Titem with given index.
uint Supply() const
Get supply of wrapped node.
static bool IsInsideMM(const T x, const uint min, const uint max)
Checks if a value is in an interval.
static void AddStats(uint new_cap, uint new_usg, uint new_flow, bool new_shared, LinkProperties &cargo)
Add information from a given pair of link stat and flow stat to the given link properties.
Offset at top to draw the frame rectangular area.
static T SetBit(T &x, const uint8 y)
Set a bit in a variable.
uint16 hover_delay_ms
time required to activate a hover event, in milliseconds
void SetCargoMask(CargoTypes cargo_mask)
Set a new cargo mask and rebuild the cache.
Window * FindWindowById(WindowClass cls, WindowNumber number)
Find a window by its class and window number.
byte _colour_gradient[COLOUR_END][8]
All 16 colour gradients 8 colours per gradient from darkest (0) to lightest (7)
Maximal number of cargo types in a game.
Specification of a cargo type.
void GuiShowTooltips(Window *parent, StringID str, uint paramcount, const uint64 params[], TooltipCloseCondition close_tooltip)
Shows a tooltip.
uint Usage() const
Get edge's usage.
static const uint8 LINK_COLOURS[]
Colours for the various "load" states of links.
void DrawCompanyIcon(CompanyID c, int x, int y)
Draw the icon of a company.
StationRect rect
NOSAVE: Station spread out rectangle maintained by StationRect::xxx() functions.
uint GetFlowVia(StationID via) const
Get the sum of flows via a specific station from this FlowStatMap.
Stores station stats for a single cargo.
Tindex index
Index of this pool item.
StringID abbrev
Two letter abbreviation for this cargo type.
void Draw(const DrawPixelInfo *dpi) const
Draw the linkgraph overlay or some part of it, in the area given.
CargoID cargo
Cargo of this component's link graph.
uint scale
Width of link lines.
static T max(const T a, const T b)
Returns the maximum of two values.
void RebuildCache()
Rebuild the cache and recalculate which links and stations to be shown.
GoodsEntry goods[NUM_CARGO]
Goods at this station.
StringID name
Name of this type of cargo.
void DrawStationDots(const DrawPixelInfo *dpi) const
Draw dots for stations into the smallmap.
A connected component of a link graph.
Data structure for an opened window.
Main window; Window numbers:
#define FONT_HEIGHT_SMALL
Height of characters in the small (FS_SMALL) font.
LinkGraphID link_graph
Link graph this station belongs to.
Class managing the smallmap window.
void UpdateOverlayCargoes()
Update the overlay with the new cargo selection.
byte road_side
the side of the road vehicles drive on
void GetWidgetDpi(DrawPixelInfo *dpi) const
Get a DPI for the widget we will be drawing to.
void SetCompanyMask(uint32 company_mask)
Set a new company mask and rebuild the cache.
Linkgraph legend; Window numbers:
ClientSettings _settings_client
The current settings for this game.
uint Monthly(uint base) const
Scale a value to its monthly equivalent, based on last compression.
bool IsPointVisible(Point pt, const DrawPixelInfo *dpi, int padding=0) const
Determine if a certain point is inside the given DPI, with some lee way.
First company, same as owner.
static uint CeilDiv(uint a, uint b)
Computes ceil(a / b) for non-negative a and b.
NodeID node
ID of node in link graph referring to this goods entry.
bool shared
If this is a shared link to be drawn dashed.
The tile has no ownership.
Offset at bottom to draw the frame rectangular area.
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.
Offset of the caption text at the left.
An iterator for const edges.
#define lengthof(x)
Return the length of an fixed size array.
static T min(const T a, const T b)
Returns the minimum of two values.
virtual void DrawWidget(const Rect &r, int widget) const
Draw the contents of a nested widget.
const uint widget_id
ID of Widget in Window to be drawn to.
uint32 StringID
Numeric value that represents a string, independent of the selected language.
Wrapper for an edge (const or not) allowing retrieval, but no modification.
Maximum number of companies.
FlowStatMap flows
Planned flows through this station.
Dimension GetStringBoundingBox(const char *str, FontSize start_fontsize)
Return the string dimension in pixels.
void AddLinks(const Station *sta, const Station *stb)
Add all "interesting" links between the given stations to the cache.
OwnerByte owner
The owner of this station.
static void DrawVertex(int x, int y, int size, int colour, int border_colour)
Draw a square symbolizing a producer of cargo.
Dimension maxdim(const Dimension &d1, const Dimension &d2)
Compute bounding box of both dimensions.
No window, redirects to WC_MAIN_WINDOW.
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.
GUISettings gui
settings related to the GUI
static CargoSpec * Get(size_t index)
Retrieve cargo details for the given cargo ID.
TextColour GetContrastColour(uint8 background, uint8 threshold)
Determine a contrasty text colour for a coloured background.
bool IsLinkVisible(Point pta, Point ptb, const DrawPixelInfo *dpi, int padding=0) const
Determine if a certain link crosses through the area given by the dpi with some lee way...
uint32 company_mask
Bitmask of companies to be displayed.
static T abs(const T a)
Returns the absolute value of (scalar) variable.
void ShowLinkGraphLegend()
Open a link graph legend window.
virtual void OnInvalidateData(int data=0, bool gui_scope=true)
Invalidate the data of this window if the cargoes or companies have changed.
virtual bool OnRightClick(Point pt, int widget)
A click with the right mouse button has been made on the window.
ConstEdgeIterator End() const
Get an iterator pointing beyond the end of the edges array.
const Window * window
Window to be drawn into.
CargoTypes cargo_mask
Bitmask of cargos to be displayed.
static bool IsValidID(size_t index)
Tests whether given index is a valid index for station of this type.
Coordinates of a point in 2D.
Dimension GetSpriteSize(SpriteID sprid, Point *offset, ZoomLevel zoom)
Get the size of a sprite.
static bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-NULL) Titem.
void DrawContent(Point pta, Point ptb, const LinkProperties &cargo) const
Draw one specific link.
Offset at right to draw the frame rectangular area.
uint capacity
Capacity of the link.
static bool HasBit(const T x, const uint8 y)
Checks if a bit in a value is set.
bool IsValid() const
Tests for validity of this cargospec.
Specification of a rectangle with absolute coordinates of all edges.
byte CargoID
Cargo slots to indicate a cargo type within a game.
Owner
Enum for all companies/owners.
void DrawLinks(const DrawPixelInfo *dpi) const
Draw the cached links or part of them into the given area.
Find a place automatically.
ViewportData * viewport
Pointer to viewport data, if present.
ConstEdgeIterator Begin() const
Get an iterator pointing to the start of the edges array.
uint Capacity() const
Get edge's capacity.
static Station * Get(size_t index)
Gets station with given index.
const NWID * GetWidget(uint widnum) const
Get the nested widget with number widnum from the nested widget tree.
CargoTypes GetCargoMask()
Get a bitmask of the currently shown cargoes.
NWidgetBase * MakeCompanyButtonRowsLinkGraphGUI(int *biggest_index)
Make a number of rows with buttons for each company for the linkgraph legend window.
Dimensions (a width and height) of a rectangle in 2D.
Offset at left to draw the frame rectangular area.
void UpdateOverlayCompanies()
Update the overlay with the new company selection.
Point GetStationMiddle(const Station *st) const
Determine the middle of a station in the current window.
Handles drawing of links into some window.
uint planned
Planned usage of the link.
StationSupplyList cached_stations
Cache for stations to be drawn.
static Station * GetIfValid(size_t index)
Returns station if the index is a valid index for this station type.