Implement reset, copy, share and unshare of trace restrict programs.
Add documentation on data storage model, wrt lookup, mapping and sharing.
This commit is contained in:
@@ -2396,14 +2396,23 @@ STR_TRACE_RESTRICT_PF_ALLOW_LONG :Allow (cancel p
|
||||
STR_TRACE_RESTRICT_PF_PENALTY :Penalty
|
||||
STR_TRACE_RESTRICT_VALUE_CAPTION :{WHITE}Value
|
||||
STR_TRACE_RESTRICT_CAPTION :{WHITE}Routefinding restriction
|
||||
STR_TRACE_RESTRICT_CAPTION_SHARED :{WHITE}Routefinding restriction - shared by {COMMA} signals
|
||||
STR_TRACE_RESTRICT_TYPE_TOOLTIP :{BLACK}Type
|
||||
STR_TRACE_RESTRICT_COND_COMPARATOR_TOOLTIP :{BLACK}Comparison operator
|
||||
STR_TRACE_RESTRICT_COND_VALUE_TOOLTIP :{BLACK}Value
|
||||
STR_TRACE_RESTRICT_GOTO_SIGNAL_TOOLTIP :{BLACK}Go to signal
|
||||
STR_TRACE_RESTRICT_INSERT :{BLACK}Insert
|
||||
STR_TRACE_RESTRICT_REMOVE :{BLACK}Remove
|
||||
STR_TRACE_RESTRICT_RESET :{BLACK}Reset
|
||||
STR_TRACE_RESTRICT_COPY :{BLACK}Copy
|
||||
STR_TRACE_RESTRICT_SHARE :{BLACK}Share
|
||||
STR_TRACE_RESTRICT_UNSHARE :{BLACK}Unshare
|
||||
STR_TRACE_RESTRICT_INSERT_TOOLTIP :{BLACK}Insert an instruction
|
||||
STR_TRACE_RESTRICT_REMOVE_TOOLTIP :{BLACK}Remove the selected instruction
|
||||
STR_TRACE_RESTRICT_RESET_TOOLTIP :{BLACK}Reset the current signal (without affecting shared programs)
|
||||
STR_TRACE_RESTRICT_COPY_TOOLTIP :{BLACK}Copy program from another signal
|
||||
STR_TRACE_RESTRICT_SHARE_TOOLTIP :{BLACK}Share program with another signal
|
||||
STR_TRACE_RESTRICT_UNSHARE_TOOLTIP :{BLACK}Stop sharing program with other signals, create a copy of the program
|
||||
STR_TRACE_RESTRICT_SIGNAL_GUI_TOOLTIP :{BLACK}Routefinding restriction
|
||||
STR_TRACE_RESTRICT_ERROR_CAN_T_INSERT_ITEM :{WHITE}Can't insert instruction
|
||||
STR_TRACE_RESTRICT_ERROR_CAN_T_MODIFY_ITEM :{WHITE}Can't modify instruction
|
||||
@@ -2417,6 +2426,11 @@ STR_TRACE_RESTRICT_ERROR_VALIDATE_END_CONDSTACK :Validation fail
|
||||
STR_TRACE_RESTRICT_ERROR_VALIDATE_NO_IF :Validation failed: else/endif without opening if
|
||||
STR_TRACE_RESTRICT_ERROR_VALIDATE_DUP_ELSE :Validation failed: duplicate else
|
||||
STR_TRACE_RESTRICT_ERROR_VALIDATE_ELIF_NO_IF :Validation failed: else if without opening if
|
||||
STR_TRACE_RESTRICT_ERROR_SOURCE_SAME_AS_TARGET :Source and target signals are the same
|
||||
STR_TRACE_RESTRICT_ERROR_CAN_T_RESET_SIGNAL :{WHITE}Can't reset signal
|
||||
STR_TRACE_RESTRICT_ERROR_CAN_T_COPY_PROGRAM :{WHITE}Can't copy program
|
||||
STR_TRACE_RESTRICT_ERROR_CAN_T_SHARE_PROGRAM :{WHITE}Can't share program
|
||||
STR_TRACE_RESTRICT_ERROR_CAN_T_UNSHARE_PROGRAM :{WHITE}Can't unshare program
|
||||
|
||||
# Bridge selection window
|
||||
STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Select Rail Bridge
|
||||
|
@@ -19,7 +19,40 @@
|
||||
#include "pathfinder/yapf/yapf_cache.h"
|
||||
#include <vector>
|
||||
|
||||
/** Initialize theprogram pool */
|
||||
/** Trace Restrict Data Storage Model Notes:
|
||||
*
|
||||
* Signals may have 0, 1 or 2 trace restrict programs attached to them,
|
||||
* up to one for each track. Two-way signals share the same program.
|
||||
*
|
||||
* The mapping between signals and programs is defined in terms of
|
||||
* TraceRestrictRefId to TraceRestrictProgramID,
|
||||
* where TraceRestrictRefId is formed of the tile index and track,
|
||||
* and TraceRestrictProgramID is an index into the program pool.
|
||||
*
|
||||
* If one or more mappings exist for a given signal tile, bit 12 of M3 will be set to 1.
|
||||
* This is updated whenever mappings are added/removed for that tile. This is to avoid
|
||||
* needing to do a mapping lookup for the common case where there is no trace restrict
|
||||
* program mapping for the given tile.
|
||||
*
|
||||
* Programs in the program pool are refcounted based on the number of mappings which exist.
|
||||
* When this falls to 0, the program is deleted from the pool.
|
||||
* If a program has a refcount greater than 1, it is a shared program.
|
||||
*
|
||||
* In all cases, an empty program is evaluated the same as the absence of a program.
|
||||
* Therefore it is not necessary to store mappings to empty unshared programs.
|
||||
* Any editing action which would otherwise result in a mapping to an empty program
|
||||
* which has no other references, instead removes the mapping.
|
||||
* This is not done for shared programs as this would delete the shared aspect whenever
|
||||
* the program became empty.
|
||||
*
|
||||
* Empty programs with a refcount of 1 may still exist due to the edge case where:
|
||||
* 1: There is an empty program with refcount 2
|
||||
* 2: One of the two mappings is deleted
|
||||
* Finding the other mapping would entail a linear search of the mappings, and there is little
|
||||
* to be gained by doing so.
|
||||
*/
|
||||
|
||||
/** Initialize the program pool */
|
||||
TraceRestrictProgramPool _tracerestrictprogram_pool("TraceRestrictProgram");
|
||||
INSTANTIATE_POOL_METHODS(TraceRestrictProgram)
|
||||
|
||||
@@ -353,27 +386,8 @@ void TraceRestrictDoCommandP(TileIndex tile, Track track, TraceRestrictDoCommand
|
||||
DoCommandP(tile, p1, value, CMD_PROGRAM_TRACERESTRICT_SIGNAL | CMD_MSG(error_msg));
|
||||
}
|
||||
|
||||
/**
|
||||
* The main command for editing a signal tracerestrict program.
|
||||
* @param tile The tile which contains the signal.
|
||||
* @param flags Internal command handler stuff.
|
||||
* @param p1 Bitstuffed items
|
||||
* @param p2 Item, for insert and modify operations
|
||||
* @return the cost of this operation (which is free), or an error
|
||||
*/
|
||||
CommandCost CmdProgramSignalTraceRestrict(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||
static CommandCost TraceRestrictCheckTileIsUsable(TileIndex tile, Track track)
|
||||
{
|
||||
Track track = static_cast<Track>(GB(p1, 0, 3));
|
||||
TraceRestrictDoCommandType type = static_cast<TraceRestrictDoCommandType>(GB(p1, 3, 5));
|
||||
uint32 offset = GB(p1, 8, 16);
|
||||
TraceRestrictItem item = static_cast<TraceRestrictItem>(p2);
|
||||
|
||||
// Check tile ownership
|
||||
CommandCost ret = CheckTileOwnership(tile);
|
||||
if (ret.Failed()) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Check that there actually is a signal here
|
||||
if (!IsPlainRailTile(tile) || !HasTrack(tile, track)) {
|
||||
return_cmd_error(STR_ERROR_THERE_IS_NO_RAILROAD_TRACK);
|
||||
@@ -382,6 +396,41 @@ CommandCost CmdProgramSignalTraceRestrict(TileIndex tile, DoCommandFlag flags, u
|
||||
return_cmd_error(STR_ERROR_THERE_ARE_NO_SIGNALS);
|
||||
}
|
||||
|
||||
// Check tile ownership, do this afterwards to avoid tripping up on house/industry tiles
|
||||
CommandCost ret = CheckTileOwnership(tile);
|
||||
if (ret.Failed()) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return CommandCost();
|
||||
}
|
||||
|
||||
/**
|
||||
* The main command for editing a signal tracerestrict program.
|
||||
* @param tile The tile which contains the signal.
|
||||
* @param flags Internal command handler stuff.
|
||||
* Below apply for instruction modification actions only
|
||||
* @param p1 Bitstuffed items
|
||||
* @param p2 Item, for insert and modify operations
|
||||
* @return the cost of this operation (which is free), or an error
|
||||
*/
|
||||
CommandCost CmdProgramSignalTraceRestrict(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||
{
|
||||
TraceRestrictDoCommandType type = static_cast<TraceRestrictDoCommandType>(GB(p1, 3, 5));
|
||||
|
||||
if (type >= TRDCT_PROG_COPY) {
|
||||
return CmdProgramSignalTraceRestrictProgMgmt(tile, flags, p1, p2, text);
|
||||
}
|
||||
|
||||
Track track = static_cast<Track>(GB(p1, 0, 3));
|
||||
uint32 offset = GB(p1, 8, 16);
|
||||
TraceRestrictItem item = static_cast<TraceRestrictItem>(p2);
|
||||
|
||||
CommandCost ret = TraceRestrictCheckTileIsUsable(tile, track);
|
||||
if (ret.Failed()) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool can_make_new = (type == TRDCT_INSERT_ITEM) && (flags & DC_EXEC);
|
||||
bool need_existing = (type != TRDCT_INSERT_ITEM);
|
||||
TraceRestrictProgram *prog = GetTraceRestrictProgram(MakeTraceRestrictRefId(tile, track), can_make_new);
|
||||
@@ -508,3 +557,120 @@ CommandCost CmdProgramSignalTraceRestrict(TileIndex tile, DoCommandFlag flags, u
|
||||
|
||||
return CommandCost();
|
||||
}
|
||||
|
||||
void TraceRestrictProgMgmtWithSourceDoCommandP(TileIndex tile, Track track, TraceRestrictDoCommandType type,
|
||||
TileIndex source_tile, Track source_track, StringID error_msg)
|
||||
{
|
||||
uint32 p1 = 0;
|
||||
SB(p1, 0, 3, track);
|
||||
SB(p1, 3, 5, type);
|
||||
SB(p1, 8, 3, source_track);
|
||||
DoCommandP(tile, p1, source_tile, CMD_PROGRAM_TRACERESTRICT_SIGNAL | CMD_MSG(error_msg));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sub command for copy/share/unshare operations on signal tracerestrict programs.
|
||||
* @param tile The tile which contains the signal.
|
||||
* @param flags Internal command handler stuff.
|
||||
* @param p1 Bitstuffed items
|
||||
* @param p2 Source tile, for share/copy operations
|
||||
* @return the cost of this operation (which is free), or an error
|
||||
*/
|
||||
CommandCost CmdProgramSignalTraceRestrictProgMgmt(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||
{
|
||||
TraceRestrictDoCommandType type = static_cast<TraceRestrictDoCommandType>(GB(p1, 3, 5));
|
||||
Track track = static_cast<Track>(GB(p1, 0, 3));
|
||||
Track source_track = static_cast<Track>(GB(p1, 8, 3));
|
||||
TileIndex source_tile = static_cast<TileIndex>(p2);
|
||||
|
||||
TraceRestrictRefId self = MakeTraceRestrictRefId(tile, track);
|
||||
TraceRestrictRefId source = MakeTraceRestrictRefId(source_tile, source_track);
|
||||
|
||||
assert(type >= TRDCT_PROG_COPY);
|
||||
|
||||
CommandCost ret = TraceRestrictCheckTileIsUsable(tile, track);
|
||||
if (ret.Failed()) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (type == TRDCT_PROG_SHARE || type == TRDCT_PROG_COPY) {
|
||||
if (self == source) {
|
||||
return_cmd_error(STR_TRACE_RESTRICT_ERROR_SOURCE_SAME_AS_TARGET);
|
||||
}
|
||||
|
||||
ret = TraceRestrictCheckTileIsUsable(source_tile, source_track);
|
||||
if (ret.Failed()) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(flags & DC_EXEC)) {
|
||||
return CommandCost();
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case TRDCT_PROG_COPY: {
|
||||
TraceRestrictRemoveProgramMapping(self);
|
||||
TraceRestrictProgram *prog = GetTraceRestrictProgram(self, true);
|
||||
if (!prog) {
|
||||
// allocation failed
|
||||
return CMD_ERROR;
|
||||
}
|
||||
|
||||
TraceRestrictProgram *source_prog = GetTraceRestrictProgram(source, false);
|
||||
if (source_prog) {
|
||||
prog->items = source_prog->items; // copy
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TRDCT_PROG_SHARE: {
|
||||
TraceRestrictRemoveProgramMapping(self);
|
||||
TraceRestrictProgram *source_prog = GetTraceRestrictProgram(source, true);
|
||||
if (!source_prog) {
|
||||
// allocation failed
|
||||
return CMD_ERROR;
|
||||
}
|
||||
|
||||
TraceRestrictCreateProgramMapping(self, source_prog);
|
||||
break;
|
||||
}
|
||||
|
||||
case TRDCT_PROG_UNSHARE: {
|
||||
std::vector<TraceRestrictItem> items;
|
||||
TraceRestrictProgram *prog = GetTraceRestrictProgram(self, false);
|
||||
if (prog) {
|
||||
// copy program into temporary
|
||||
items = prog->items;
|
||||
}
|
||||
// remove old program
|
||||
TraceRestrictRemoveProgramMapping(self);
|
||||
|
||||
if (items.size()) {
|
||||
// if prog is non-empty, create new program and move temporary in
|
||||
TraceRestrictProgram *new_prog = GetTraceRestrictProgram(self, true);
|
||||
if (!new_prog) {
|
||||
// allocation failed
|
||||
return CMD_ERROR;
|
||||
}
|
||||
|
||||
new_prog->items.swap(items);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TRDCT_PROG_RESET: {
|
||||
TraceRestrictRemoveProgramMapping(self);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
NOT_REACHED();
|
||||
break;
|
||||
}
|
||||
|
||||
// update windows
|
||||
InvalidateWindowClassesData(WC_TRACE_RESTRICT);
|
||||
|
||||
return CommandCost();
|
||||
}
|
||||
|
@@ -269,15 +269,30 @@ static inline const TraceRestrictProgram *GetExistingTraceRestrictProgram(TileIn
|
||||
}
|
||||
}
|
||||
|
||||
// do not re-order
|
||||
enum TraceRestrictDoCommandType {
|
||||
TRDCT_INSERT_ITEM = 0,
|
||||
TRDCT_MODIFY_ITEM = 1,
|
||||
TRDCT_REMOVE_ITEM = 2,
|
||||
|
||||
TRDCT_PROG_COPY = 3,
|
||||
TRDCT_PROG_SHARE = 4,
|
||||
TRDCT_PROG_UNSHARE = 5,
|
||||
TRDCT_PROG_RESET = 6,
|
||||
};
|
||||
|
||||
void TraceRestrictDoCommandP(TileIndex tile, Track track, TraceRestrictDoCommandType type, uint32 offset, uint32 value, StringID error_msg);
|
||||
|
||||
void TraceRestrictProgMgmtWithSourceDoCommandP(TileIndex tile, Track track, TraceRestrictDoCommandType type,
|
||||
TileIndex source_tile, Track source_track, StringID error_msg);
|
||||
|
||||
inline void TraceRestrictProgMgmtDoCommandP(TileIndex tile, Track track, TraceRestrictDoCommandType type, StringID error_msg)
|
||||
{
|
||||
TraceRestrictProgMgmtWithSourceDoCommandP(tile, track, type, static_cast<TileIndex>(0), static_cast<Track>(0), error_msg);
|
||||
}
|
||||
|
||||
CommandCost CmdProgramSignalTraceRestrict(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text);
|
||||
CommandCost CmdProgramSignalTraceRestrictProgMgmt(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text);
|
||||
|
||||
void ShowTraceRestrictProgramWindow(TileIndex tile, Track track);
|
||||
|
||||
|
@@ -18,6 +18,7 @@
|
||||
#include "viewport_func.h"
|
||||
#include "textbuf_gui.h"
|
||||
#include "company_func.h"
|
||||
#include "tilehighlight_func.h"
|
||||
#include "widgets/dropdown_func.h"
|
||||
#include "gui.h"
|
||||
#include "gfx_func.h"
|
||||
@@ -34,6 +35,7 @@ enum TraceRestrictWindowWidgets {
|
||||
TR_WIDGET_SEL_TOP_LEFT,
|
||||
TR_WIDGET_SEL_TOP_MIDDLE,
|
||||
TR_WIDGET_SEL_TOP_RIGHT,
|
||||
TR_WIDGET_SEL_SHARE,
|
||||
|
||||
TR_WIDGET_TYPE,
|
||||
TR_WIDGET_COMPARATOR,
|
||||
@@ -47,6 +49,10 @@ enum TraceRestrictWindowWidgets {
|
||||
TR_WIDGET_GOTO_SIGNAL,
|
||||
TR_WIDGET_INSERT,
|
||||
TR_WIDGET_REMOVE,
|
||||
TR_WIDGET_RESET,
|
||||
TR_WIDGET_COPY,
|
||||
TR_WIDGET_SHARE,
|
||||
TR_WIDGET_UNSHARE,
|
||||
};
|
||||
|
||||
enum PanelWidgets {
|
||||
@@ -62,6 +68,10 @@ enum PanelWidgets {
|
||||
DPR_VALUE_INT = 0,
|
||||
DPR_VALUE_DROPDOWN,
|
||||
DPR_BLANK,
|
||||
|
||||
// Share
|
||||
DPS_SHARE = 0,
|
||||
DPS_UNSHARE,
|
||||
};
|
||||
|
||||
/// value_array *must* be at least as long as string_array,
|
||||
@@ -293,6 +303,7 @@ class TraceRestrictWindow: public Window {
|
||||
Scrollbar *vscroll;
|
||||
std::map<int, const TraceRestrictDropDownListSet *> drop_down_list_mapping;
|
||||
TraceRestrictItem expecting_inserted_item;
|
||||
int current_placement_widget;
|
||||
|
||||
public:
|
||||
TraceRestrictWindow(WindowDesc *desc, TileIndex tile, Track track)
|
||||
@@ -302,6 +313,7 @@ public:
|
||||
this->track = track;
|
||||
this->selected_instruction = -1;
|
||||
this->expecting_inserted_item = static_cast<TraceRestrictItem>(0);
|
||||
this->current_placement_widget = -1;
|
||||
|
||||
this->CreateNestedTree();
|
||||
this->vscroll = this->GetScrollbar(TR_WIDGET_SCROLLBAR);
|
||||
@@ -389,6 +401,21 @@ public:
|
||||
case TR_WIDGET_GOTO_SIGNAL:
|
||||
ScrollMainWindowToTile(this->tile);
|
||||
break;
|
||||
|
||||
case TR_WIDGET_RESET: {
|
||||
TraceRestrictProgMgmtDoCommandP(tile, track, TRDCT_PROG_RESET, STR_TRACE_RESTRICT_ERROR_CAN_T_RESET_SIGNAL);
|
||||
break;
|
||||
}
|
||||
|
||||
case TR_WIDGET_COPY:
|
||||
case TR_WIDGET_SHARE:
|
||||
SelectSignalAction(widget);
|
||||
break;
|
||||
|
||||
case TR_WIDGET_UNSHARE: {
|
||||
TraceRestrictProgMgmtDoCommandP(tile, track, TRDCT_PROG_UNSHARE, STR_TRACE_RESTRICT_ERROR_CAN_T_UNSHARE_PROGRAM);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -457,6 +484,72 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnPlaceObject(Point pt, TileIndex source_tile)
|
||||
{
|
||||
int widget = this->current_placement_widget;
|
||||
this->current_placement_widget = -1;
|
||||
|
||||
this->RaiseButtons();
|
||||
ResetObjectToPlace();
|
||||
|
||||
if (widget < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
int error_message = (widget == TR_WIDGET_COPY) ? STR_TRACE_RESTRICT_ERROR_CAN_T_COPY_PROGRAM : STR_TRACE_RESTRICT_ERROR_CAN_T_SHARE_PROGRAM;
|
||||
|
||||
if (!IsPlainRailTile(source_tile)) {
|
||||
ShowErrorMessage(error_message, STR_ERROR_THERE_IS_NO_RAILROAD_TRACK, WL_INFO);
|
||||
return;
|
||||
}
|
||||
|
||||
TrackBits trackbits = TrackStatusToTrackBits(GetTileTrackStatus(source_tile, TRANSPORT_RAIL, 0));
|
||||
if (trackbits & TRACK_BIT_VERT) { // N-S direction
|
||||
trackbits = (_tile_fract_coords.x <= _tile_fract_coords.y) ? TRACK_BIT_RIGHT : TRACK_BIT_LEFT;
|
||||
}
|
||||
|
||||
if (trackbits & TRACK_BIT_HORZ) { // E-W direction
|
||||
trackbits = (_tile_fract_coords.x + _tile_fract_coords.y <= 15) ? TRACK_BIT_UPPER : TRACK_BIT_LOWER;
|
||||
}
|
||||
Track source_track = FindFirstTrack(trackbits);
|
||||
if(source_track == INVALID_TRACK) {
|
||||
ShowErrorMessage(error_message, STR_ERROR_THERE_IS_NO_RAILROAD_TRACK, WL_INFO);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!HasTrack(source_tile, source_track)) {
|
||||
ShowErrorMessage(error_message, STR_ERROR_THERE_IS_NO_RAILROAD_TRACK, WL_INFO);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!HasSignalOnTrack(source_tile, source_track)) {
|
||||
ShowErrorMessage(error_message, STR_ERROR_THERE_ARE_NO_SIGNALS, WL_INFO);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (widget) {
|
||||
case TR_WIDGET_COPY:
|
||||
TraceRestrictProgMgmtWithSourceDoCommandP(this->tile, this->track, TRDCT_PROG_COPY,
|
||||
source_tile, source_track, STR_TRACE_RESTRICT_ERROR_CAN_T_COPY_PROGRAM);
|
||||
break;
|
||||
|
||||
case TR_WIDGET_SHARE:
|
||||
TraceRestrictProgMgmtWithSourceDoCommandP(this->tile, this->track, TRDCT_PROG_SHARE,
|
||||
source_tile, source_track, STR_TRACE_RESTRICT_ERROR_CAN_T_SHARE_PROGRAM);
|
||||
break;
|
||||
|
||||
default:
|
||||
NOT_REACHED();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnPlaceObjectAbort()
|
||||
{
|
||||
this->RaiseButtons();
|
||||
this->current_placement_widget = -1;
|
||||
}
|
||||
|
||||
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
|
||||
{
|
||||
switch (widget) {
|
||||
@@ -531,7 +624,18 @@ public:
|
||||
if (GetTraceRestrictTypeProperties(item).value_type == TRVT_INT) {
|
||||
SetDParam(0, GetTraceRestrictValue(item));
|
||||
}
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
case TR_WIDGET_CAPTION: {
|
||||
const TraceRestrictProgram *prog = this->GetProgram();
|
||||
if (prog) {
|
||||
SetDParam(0, prog->refcount);
|
||||
} else {
|
||||
SetDParam(0, 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -646,6 +750,7 @@ private:
|
||||
NWidgetStacked *left_sel = this->GetWidget<NWidgetStacked>(TR_WIDGET_SEL_TOP_LEFT);
|
||||
NWidgetStacked *middle_sel = this->GetWidget<NWidgetStacked>(TR_WIDGET_SEL_TOP_MIDDLE);
|
||||
NWidgetStacked *right_sel = this->GetWidget<NWidgetStacked>(TR_WIDGET_SEL_TOP_RIGHT);
|
||||
NWidgetStacked *share_sel = this->GetWidget<NWidgetStacked>(TR_WIDGET_SEL_SHARE);
|
||||
|
||||
this->DisableWidget(TR_WIDGET_TYPE);
|
||||
this->DisableWidget(TR_WIDGET_COMPARATOR);
|
||||
@@ -654,6 +759,10 @@ private:
|
||||
|
||||
this->DisableWidget(TR_WIDGET_INSERT);
|
||||
this->DisableWidget(TR_WIDGET_REMOVE);
|
||||
this->DisableWidget(TR_WIDGET_RESET);
|
||||
this->DisableWidget(TR_WIDGET_COPY);
|
||||
this->DisableWidget(TR_WIDGET_SHARE);
|
||||
this->DisableWidget(TR_WIDGET_UNSHARE);
|
||||
|
||||
this->DisableWidget(TR_WIDGET_BLANK_L);
|
||||
this->DisableWidget(TR_WIDGET_BLANK_M);
|
||||
@@ -662,14 +771,40 @@ private:
|
||||
left_sel->SetDisplayedPlane(DPL_BLANK);
|
||||
middle_sel->SetDisplayedPlane(DPM_BLANK);
|
||||
right_sel->SetDisplayedPlane(DPR_BLANK);
|
||||
share_sel->SetDisplayedPlane(DPS_SHARE);
|
||||
|
||||
// Don't allow modifications if don't own, or have selected invalid instruction
|
||||
if (this->GetOwner() != _local_company || this->selected_instruction < 1) {
|
||||
const TraceRestrictProgram *prog = this->GetProgram();
|
||||
|
||||
this->GetWidget<NWidgetCore>(TR_WIDGET_CAPTION)->widget_data =
|
||||
(prog && prog->refcount > 1) ? STR_TRACE_RESTRICT_CAPTION_SHARED : STR_TRACE_RESTRICT_CAPTION;
|
||||
|
||||
// Don't allow modifications if don't own
|
||||
if (this->GetOwner() != _local_company) {
|
||||
this->SetDirty();
|
||||
return;
|
||||
}
|
||||
|
||||
TraceRestrictItem item = this->GetSelected();
|
||||
if (prog && prog->refcount > 1) {
|
||||
// program is shared, show and enable unshare button, and reset button
|
||||
share_sel->SetDisplayedPlane(DPS_UNSHARE);
|
||||
this->EnableWidget(TR_WIDGET_UNSHARE);
|
||||
this->EnableWidget(TR_WIDGET_RESET);
|
||||
} else if (this->GetItemCount(prog) > 2) {
|
||||
// program is non-empty and not shared, enable reset button
|
||||
this->EnableWidget(TR_WIDGET_RESET);
|
||||
} else {
|
||||
// program is empty and not shared, show copy and share buttons
|
||||
this->EnableWidget(TR_WIDGET_COPY);
|
||||
this->EnableWidget(TR_WIDGET_SHARE);
|
||||
}
|
||||
|
||||
// haven't selected instruction
|
||||
if (this->selected_instruction < 1) {
|
||||
this->SetDirty();
|
||||
return;
|
||||
}
|
||||
|
||||
TraceRestrictItem item = this->GetItem(prog, this->selected_instruction);
|
||||
if (item != 0) {
|
||||
if (GetTraceRestrictType(item) == TRIT_NULL) {
|
||||
switch (GetTraceRestrictValue(item)) {
|
||||
@@ -736,6 +871,19 @@ private:
|
||||
int selected = GetDropDownListIndexByValue(list_set, value, missing_ok);
|
||||
ShowDropDownMenu(this, list_set->string_array, selected, button, disabled_mask, hidden_mask, width);
|
||||
}
|
||||
|
||||
void SelectSignalAction(int widget)
|
||||
{
|
||||
this->ToggleWidgetLoweredState(widget);
|
||||
this->SetWidgetDirty(widget);
|
||||
if (this->IsWidgetLowered(widget)) {
|
||||
SetObjectToPlaceWnd(ANIMCURSOR_BUILDSIGNALS, PAL_NONE, HT_RECT, this);
|
||||
this->current_placement_widget = widget;
|
||||
} else {
|
||||
ResetObjectToPlace();
|
||||
this->current_placement_widget = -1;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static const NWidgetPart _nested_program_widgets[] = {
|
||||
@@ -785,8 +933,18 @@ static const NWidgetPart _nested_program_widgets[] = {
|
||||
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
|
||||
NWidget(WWT_DROPDOWN, COLOUR_GREY, TR_WIDGET_INSERT), SetMinimalSize(124, 12), SetFill(1, 0),
|
||||
SetDataTip(STR_TRACE_RESTRICT_INSERT, STR_TRACE_RESTRICT_INSERT_TOOLTIP), SetResize(1, 0),
|
||||
NWidget(WWT_TEXTBTN, COLOUR_GREY, TR_WIDGET_REMOVE), SetMinimalSize(186, 12), SetFill(1, 0),
|
||||
NWidget(WWT_TEXTBTN, COLOUR_GREY, TR_WIDGET_REMOVE), SetMinimalSize(124, 12), SetFill(1, 0),
|
||||
SetDataTip(STR_TRACE_RESTRICT_REMOVE, STR_TRACE_RESTRICT_REMOVE_TOOLTIP), SetResize(1, 0),
|
||||
NWidget(WWT_TEXTBTN, COLOUR_GREY, TR_WIDGET_RESET), SetMinimalSize(124, 12), SetFill(1, 0),
|
||||
SetDataTip(STR_TRACE_RESTRICT_RESET, STR_TRACE_RESTRICT_RESET_TOOLTIP), SetResize(1, 0),
|
||||
NWidget(WWT_TEXTBTN, COLOUR_GREY, TR_WIDGET_COPY), SetMinimalSize(124, 12), SetFill(1, 0),
|
||||
SetDataTip(STR_TRACE_RESTRICT_COPY, STR_TRACE_RESTRICT_COPY_TOOLTIP), SetResize(1, 0),
|
||||
NWidget(NWID_SELECTION, INVALID_COLOUR, TR_WIDGET_SEL_SHARE),
|
||||
NWidget(WWT_TEXTBTN, COLOUR_GREY, TR_WIDGET_SHARE), SetMinimalSize(124, 12), SetFill(1, 0),
|
||||
SetDataTip(STR_TRACE_RESTRICT_SHARE, STR_TRACE_RESTRICT_SHARE_TOOLTIP), SetResize(1, 0),
|
||||
NWidget(WWT_TEXTBTN, COLOUR_GREY, TR_WIDGET_UNSHARE), SetMinimalSize(124, 12), SetFill(1, 0),
|
||||
SetDataTip(STR_TRACE_RESTRICT_UNSHARE, STR_TRACE_RESTRICT_UNSHARE_TOOLTIP), SetResize(1, 0),
|
||||
EndContainer(),
|
||||
EndContainer(),
|
||||
NWidget(WWT_RESIZEBOX, COLOUR_GREY),
|
||||
EndContainer(),
|
||||
|
Reference in New Issue
Block a user