/* $Id$ */
/*
* This file is part of OpenTTD .
* 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.
* 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 .
* 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/>.
*/
/** @file tracerestrict_gui.cpp GUI code for Trace Restrict
*
* This is largely based on the programmable signals patch ' s GUI
* */
# include "stdafx.h"
# include "tracerestrict.h"
# include "command_func.h"
# include "window_func.h"
# include "strings_func.h"
# include "string_func.h"
# include "viewport_func.h"
# include "textbuf_gui.h"
# include "company_base.h"
# include "company_func.h"
# include "tilehighlight_func.h"
# include "widgets/dropdown_func.h"
# include "widgets/dropdown_type.h"
# include "gui.h"
# include "gfx_func.h"
# include "rail_map.h"
# include "depot_map.h"
# include "tile_cmd.h"
# include "station_base.h"
# include "waypoint_base.h"
# include "depot_base.h"
# include "error.h"
# include "cargotype.h"
# include "sortlist_type.h"
# include "group.h"
# include "table/sprites.h"
# include "toolbar_gui.h"
extern uint ConvertSpeedToDisplaySpeed ( uint speed ) ;
extern uint ConvertDisplaySpeedToSpeed ( uint speed ) ;
/** Widget IDs */
enum TraceRestrictWindowWidgets {
TR_WIDGET_CAPTION ,
TR_WIDGET_INSTRUCTION_LIST ,
TR_WIDGET_SCROLLBAR ,
TR_WIDGET_SEL_TOP_LEFT_2 ,
TR_WIDGET_SEL_TOP_LEFT ,
TR_WIDGET_SEL_TOP_MIDDLE ,
TR_WIDGET_SEL_TOP_RIGHT ,
TR_WIDGET_SEL_SHARE ,
TR_WIDGET_TYPE_COND ,
TR_WIDGET_TYPE_NONCOND ,
TR_WIDGET_CONDFLAGS ,
TR_WIDGET_COMPARATOR ,
TR_WIDGET_VALUE_INT ,
TR_WIDGET_VALUE_DROPDOWN ,
TR_WIDGET_VALUE_DEST ,
TR_WIDGET_VALUE_SIGNAL ,
TR_WIDGET_BLANK_L2 ,
TR_WIDGET_BLANK_L ,
TR_WIDGET_BLANK_M ,
TR_WIDGET_BLANK_R ,
TR_WIDGET_GOTO_SIGNAL ,
TR_WIDGET_INSERT ,
TR_WIDGET_REMOVE ,
TR_WIDGET_RESET ,
TR_WIDGET_COPY ,
TR_WIDGET_SHARE ,
TR_WIDGET_UNSHARE ,
} ;
/** Selection mappings for NWID_SELECTION selectors */
enum PanelWidgets {
// Left 2
DPL2_TYPE = 0 ,
DPL2_CONDFLAGS ,
DPL2_BLANK ,
// Left
DPL_TYPE = 0 ,
DPL_BLANK ,
// Middle
DPM_COMPARATOR = 0 ,
DPM_BLANK ,
// Right
DPR_VALUE_INT = 0 ,
DPR_VALUE_DROPDOWN ,
DPR_VALUE_DEST ,
DPR_VALUE_SIGNAL ,
DPR_BLANK ,
// Share
DPS_SHARE = 0 ,
DPS_UNSHARE ,
} ;
/**
* drop down list string array , and corresponding integer values
*
* value_array * must * be at least as long as string_array ,
* where the length of string_array is defined as the offset
* of the first INVALID_STRING_ID
*/
struct TraceRestrictDropDownListSet {
const StringID * string_array ;
const uint * value_array ;
} ;
static const StringID _program_insert_str [ ] = {
STR_TRACE_RESTRICT_CONDITIONAL_IF ,
STR_TRACE_RESTRICT_CONDITIONAL_ELIF ,
STR_TRACE_RESTRICT_CONDITIONAL_ORIF ,
STR_TRACE_RESTRICT_CONDITIONAL_ELSE ,
STR_TRACE_RESTRICT_PF_DENY ,
STR_TRACE_RESTRICT_PF_PENALTY ,
STR_TRACE_RESTRICT_RESERVE_THROUGH ,
STR_TRACE_RESTRICT_LONG_RESERVE ,
INVALID_STRING_ID
} ;
static const uint32 _program_insert_else_hide_mask = 8 ; ///< disable bitmask for else
static const uint32 _program_insert_or_if_hide_mask = 4 ; ///< disable bitmask for orif
static const uint32 _program_insert_else_if_hide_mask = 2 ; ///< disable bitmask for elif
static const uint _program_insert_val [ ] = {
TRIT_COND_UNDEFINED , // if block
TRIT_COND_UNDEFINED | ( TRCF_ELSE < < 16 ) , // elif block
TRIT_COND_UNDEFINED | ( TRCF_OR < < 16 ) , // orif block
TRIT_COND_ENDIF | ( TRCF_ELSE < < 16 ) , // else block
TRIT_PF_DENY , // deny
TRIT_PF_PENALTY , // penalty
TRIT_RESERVE_THROUGH , // reserve through
TRIT_LONG_RESERVE , // long reserve
} ;
/** insert drop down list strings and values */
static const TraceRestrictDropDownListSet _program_insert = {
_program_insert_str , _program_insert_val ,
} ;
static const StringID _deny_value_str [ ] = {
STR_TRACE_RESTRICT_PF_DENY ,
STR_TRACE_RESTRICT_PF_ALLOW ,
INVALID_STRING_ID
} ;
static const uint _deny_value_val [ ] = {
0 ,
1 ,
} ;
/** value drop down list for deny types strings and values */
static const TraceRestrictDropDownListSet _deny_value = {
_deny_value_str , _deny_value_val ,
} ;
static const StringID _reserve_through_value_str [ ] = {
STR_TRACE_RESTRICT_RESERVE_THROUGH ,
STR_TRACE_RESTRICT_RESERVE_THROUGH_CANCEL ,
INVALID_STRING_ID
} ;
static const uint _reserve_through_value_val [ ] = {
0 ,
1 ,
} ;
/** value drop down list for deny types strings and values */
static const TraceRestrictDropDownListSet _reserve_through_value = {
_reserve_through_value_str , _reserve_through_value_val ,
} ;
static const StringID _long_reserve_value_str [ ] = {
STR_TRACE_RESTRICT_LONG_RESERVE ,
STR_TRACE_RESTRICT_LONG_RESERVE_CANCEL ,
INVALID_STRING_ID
} ;
static const uint _long_reserve_value_val [ ] = {
0 ,
1 ,
} ;
/** value drop down list for long reserve types strings and values */
static const TraceRestrictDropDownListSet _long_reserve_value = {
_long_reserve_value_str , _long_reserve_value_val ,
} ;
static const StringID _direction_value_str [ ] = {
STR_TRACE_RESTRICT_DIRECTION_FRONT ,
STR_TRACE_RESTRICT_DIRECTION_BACK ,
STR_TRACE_RESTRICT_DIRECTION_NE ,
STR_TRACE_RESTRICT_DIRECTION_SE ,
STR_TRACE_RESTRICT_DIRECTION_SW ,
STR_TRACE_RESTRICT_DIRECTION_NW ,
INVALID_STRING_ID
} ;
static const uint _direction_value_val [ ] = {
TRDTSV_FRONT ,
TRDTSV_BACK ,
TRNTSV_NE ,
TRNTSV_SE ,
TRNTSV_SW ,
TRNTSV_NW ,
} ;
/** value drop down list for direction type strings and values */
static const TraceRestrictDropDownListSet _direction_value = {
_direction_value_str , _direction_value_val ,
} ;
/**
* Get index of @ p value in @ p list_set
* if @ p value is not present , assert if @ p missing_ok is false , otherwise return - 1
*/
static int GetDropDownListIndexByValue ( const TraceRestrictDropDownListSet * list_set , uint value , bool missing_ok )
{
const StringID * string_array = list_set - > string_array ;
const uint * value_array = list_set - > value_array ;
for ( ; * string_array ! = INVALID_STRING_ID ; string_array + + , value_array + + ) {
if ( * value_array = = value ) {
return value_array - list_set - > value_array ;
}
}
assert ( missing_ok = = true ) ;
return - 1 ;
}
/**
* Get StringID correspoding to @ p value , in @ list_set
* @ p value must be present
*/
static StringID GetDropDownStringByValue ( const TraceRestrictDropDownListSet * list_set , uint value )
{
return list_set - > string_array [ GetDropDownListIndexByValue ( list_set , value , false ) ] ;
}
/**
* Return the appropriate type dropdown TraceRestrictDropDownListSet for the given item type @ p type
*/
static const TraceRestrictDropDownListSet * GetTypeDropDownListSet ( TraceRestrictItemType type )
{
static const StringID str_action [ ] = {
STR_TRACE_RESTRICT_PF_DENY ,
STR_TRACE_RESTRICT_PF_PENALTY ,
STR_TRACE_RESTRICT_RESERVE_THROUGH ,
STR_TRACE_RESTRICT_LONG_RESERVE ,
INVALID_STRING_ID ,
} ;
static const uint val_action [ ] = {
TRIT_PF_DENY ,
TRIT_PF_PENALTY ,
TRIT_RESERVE_THROUGH ,
TRIT_LONG_RESERVE ,
} ;
static const TraceRestrictDropDownListSet set_action = {
str_action , val_action ,
} ;
static const StringID str_cond [ ] = {
STR_TRACE_RESTRICT_VARIABLE_TRAIN_LENGTH ,
STR_TRACE_RESTRICT_VARIABLE_MAX_SPEED ,
STR_TRACE_RESTRICT_VARIABLE_CURRENT_ORDER ,
STR_TRACE_RESTRICT_VARIABLE_NEXT_ORDER ,
STR_TRACE_RESTRICT_VARIABLE_LAST_VISITED_STATION ,
STR_TRACE_RESTRICT_VARIABLE_CARGO ,
STR_TRACE_RESTRICT_VARIABLE_ENTRY_DIRECTION ,
STR_TRACE_RESTRICT_VARIABLE_PBS_ENTRY_SIGNAL ,
STR_TRACE_RESTRICT_VARIABLE_TRAIN_GROUP ,
STR_TRACE_RESTRICT_VARIABLE_TRAIN_OWNER ,
STR_TRACE_RESTRICT_VARIABLE_UNDEFINED ,
INVALID_STRING_ID ,
} ;
static const uint val_cond [ ] = {
TRIT_COND_TRAIN_LENGTH ,
TRIT_COND_MAX_SPEED ,
TRIT_COND_CURRENT_ORDER ,
TRIT_COND_NEXT_ORDER ,
TRIT_COND_LAST_STATION ,
TRIT_COND_CARGO ,
TRIT_COND_ENTRY_DIRECTION ,
TRIT_COND_PBS_ENTRY_SIGNAL ,
TRIT_COND_TRAIN_GROUP ,
TRIT_COND_TRAIN_OWNER ,
TRIT_COND_UNDEFINED ,
} ;
static const TraceRestrictDropDownListSet set_cond = {
str_cond , val_cond ,
} ;
return IsTraceRestrictTypeConditional ( type ) ? & set_cond : & set_action ;
}
/**
* Get a TraceRestrictDropDownListSet of the sorted cargo list
*/
static const TraceRestrictDropDownListSet * GetSortedCargoTypeDropDownListSet ( )
{
static StringID cargo_list_str [ NUM_CARGO + 1 ] ;
static uint cargo_list_id [ NUM_CARGO ] ;
static const TraceRestrictDropDownListSet cargo_list = {
cargo_list_str , cargo_list_id ,
} ;
for ( size_t i = 0 ; i < _sorted_standard_cargo_specs_size ; + + i ) {
const CargoSpec * cs = _sorted_cargo_specs [ i ] ;
cargo_list_str [ i ] = cs - > name ;
cargo_list_id [ i ] = cs - > Index ( ) ;
}
cargo_list_str [ _sorted_standard_cargo_specs_size ] = INVALID_STRING_ID ;
return & cargo_list ;
}
/**
* Get a DropDownList of the group list
*/
static DropDownList * GetGroupDropDownList ( Owner owner , GroupID group_id , int & selected )
{
typedef GUIList < const Group * > GUIGroupList ;
extern int CDECL GroupNameSorter ( const Group * const * a , const Group * const * b ) ;
GUIGroupList list ;
const Group * g ;
FOR_ALL_GROUPS ( g ) {
if ( g - > owner = = owner & & g - > vehicle_type = = VEH_TRAIN ) {
* list . Append ( ) = g ;
}
}
list . ForceResort ( ) ;
list . Sort ( & GroupNameSorter ) ;
DropDownList * dlist = new DropDownList ( ) ;
selected = - 1 ;
if ( group_id = = DEFAULT_GROUP ) selected = DEFAULT_GROUP ;
* dlist - > Append ( ) = new DropDownListStringItem ( STR_GROUP_DEFAULT_TRAINS , DEFAULT_GROUP , false ) ;
for ( size_t i = 0 ; i < list . Length ( ) ; + + i ) {
const Group * g = list [ i ] ;
if ( group_id = = g - > index ) selected = group_id ;
DropDownListParamStringItem * item = new DropDownListParamStringItem ( STR_GROUP_NAME , g - > index , false ) ;
item - > SetParam ( 0 , g - > index ) ;
* dlist - > Append ( ) = item ;
}
return dlist ;
}
static const StringID _cargo_cond_ops_str [ ] = {
STR_TRACE_RESTRICT_CONDITIONAL_COMPARATOR_CARGO_EQUALS ,
STR_TRACE_RESTRICT_CONDITIONAL_COMPARATOR_CARGO_NOT_EQUALS ,
INVALID_STRING_ID ,
} ;
static const uint _cargo_cond_ops_val [ ] = {
TRCO_IS ,
TRCO_ISNOT ,
} ;
/** cargo conditional operators dropdown list set */
static const TraceRestrictDropDownListSet _cargo_cond_ops = {
_cargo_cond_ops_str , _cargo_cond_ops_val ,
} ;
/**
* Get the StringID for a given CargoID @ p cargo , or STR_NEWGRF_INVALID_CARGO
*/
static StringID GetCargoStringByID ( CargoID cargo )
{
const CargoSpec * cs = CargoSpec : : Get ( cargo ) ;
return cs - > IsValid ( ) ? cs - > name : STR_NEWGRF_INVALID_CARGO ;
}
/**
* Get the StringID for a given item type @ p type
*/
static StringID GetTypeString ( TraceRestrictItemType type )
{
return GetDropDownStringByValue ( GetTypeDropDownListSet ( type ) , type ) ;
}
/**
* Get the conditional operator field drop down list set for a given type property set @ p properties
*/
static const TraceRestrictDropDownListSet * GetCondOpDropDownListSet ( TraceRestrictTypePropertySet properties )
{
static const StringID str_long [ ] = {
STR_TRACE_RESTRICT_CONDITIONAL_COMPARATOR_EQUALS ,
STR_TRACE_RESTRICT_CONDITIONAL_COMPARATOR_NOT_EQUALS ,
STR_TRACE_RESTRICT_CONDITIONAL_COMPARATOR_LESS_THAN ,
STR_TRACE_RESTRICT_CONDITIONAL_COMPARATOR_LESS_EQUALS ,
STR_TRACE_RESTRICT_CONDITIONAL_COMPARATOR_MORE_THAN ,
STR_TRACE_RESTRICT_CONDITIONAL_COMPARATOR_MORE_EQUALS ,
INVALID_STRING_ID ,
} ;
static const uint val_long [ ] = {
TRCO_IS ,
TRCO_ISNOT ,
TRCO_LT ,
TRCO_LTE ,
TRCO_GT ,
TRCO_GTE ,
} ;
static const TraceRestrictDropDownListSet set_long = {
str_long , val_long ,
} ;
static const StringID str_short [ ] = {
STR_TRACE_RESTRICT_CONDITIONAL_COMPARATOR_EQUALS ,
STR_TRACE_RESTRICT_CONDITIONAL_COMPARATOR_NOT_EQUALS ,
INVALID_STRING_ID ,
} ;
static const uint val_short [ ] = {
TRCO_IS ,
TRCO_ISNOT ,
} ;
static const TraceRestrictDropDownListSet set_short = {
str_short , val_short ,
} ;
if ( properties . value_type = = TRVT_CARGO_ID ) return & _cargo_cond_ops ;
switch ( properties . cond_type ) {
case TRCOT_NONE :
return NULL ;
case TRCOT_BINARY :
return & set_short ;
case TRCOT_ALL :
return & set_long ;
}
NOT_REACHED ( ) ;
return NULL ;
}
/**
* Return true if item type field @ p type is an integer value type
*/
static bool IsIntegerValueType ( TraceRestrictValueType type )
{
switch ( type ) {
case TRVT_INT :
case TRVT_SPEED :
return true ;
default :
return false ;
}
}
/**
* Convert integer values or custom penalty values between internal units and display units
*/
static uint ConvertIntegerValue ( TraceRestrictValueType type , uint in , bool to_display )
{
switch ( type ) {
case TRVT_INT :
return in ;
case TRVT_SPEED :
return to_display
? ConvertSpeedToDisplaySpeed ( in ) * 10 / 16
: ConvertDisplaySpeedToSpeed ( in ) * 16 / 10 ;
case TRVT_PF_PENALTY :
return in ;
default :
NOT_REACHED ( ) ;
return 0 ;
}
}
/** String values for TraceRestrictCondFlags, value gives offset into array */
static const StringID _program_cond_type [ ] = {
STR_TRACE_RESTRICT_CONDITIONAL_IF , // TRCF_DEFAULT
STR_TRACE_RESTRICT_CONDITIONAL_ELIF , // TRCF_ELSE
STR_TRACE_RESTRICT_CONDITIONAL_ORIF , // TRCF_OR
} ;
/** condition flags field drop down value types */
enum CondFlagsDropDownType {
CFDDT_ELSE = 0 , ///< This is an else block
CFDDT_ELIF = TRCF_ELSE , ///< This is an else-if block
CFDDT_ORIF = TRCF_OR , ///< This is an or-if block
} ;
static const uint32 _condflags_dropdown_else_hide_mask = 1 ; ///< disable bitmask for CFDDT_ELSE
static const uint32 _condflags_dropdown_else_if_hide_mask = 6 ; ///< disable bitmask for CFDDT_ELIF and CFDDT_ORIF
static const StringID _condflags_dropdown_str [ ] = {
STR_TRACE_RESTRICT_CONDITIONAL_ELSE ,
STR_TRACE_RESTRICT_CONDITIONAL_ELIF ,
STR_TRACE_RESTRICT_CONDITIONAL_ORIF ,
INVALID_STRING_ID ,
} ;
static const uint _condflags_dropdown_val [ ] = {
CFDDT_ELSE ,
CFDDT_ELIF ,
CFDDT_ORIF ,
} ;
/** condition flags dropdown list set */
static const TraceRestrictDropDownListSet _condflags_dropdown = {
_condflags_dropdown_str , _condflags_dropdown_val ,
} ;
static const StringID _pf_penalty_dropdown_str [ ] = {
STR_TRACE_RESTRICT_PF_VALUE_SMALL ,
STR_TRACE_RESTRICT_PF_VALUE_MEDIUM ,
STR_TRACE_RESTRICT_PF_VALUE_LARGE ,
STR_TRACE_RESTRICT_PF_VALUE_CUSTOM ,
INVALID_STRING_ID ,
} ;
static const uint _pf_penalty_dropdown_val [ ] = {
TRPPPI_SMALL ,
TRPPPI_MEDIUM ,
TRPPPI_LARGE ,
TRPPPI_END , // this is a placeholder for "custom"
} ;
/** Pathfinder penalty dropdown set */
static const TraceRestrictDropDownListSet _pf_penalty_dropdown = {
_pf_penalty_dropdown_str , _pf_penalty_dropdown_val ,
} ;
static uint GetPathfinderPenaltyDropdownIndex ( TraceRestrictItem item )
{
switch ( static_cast < TraceRestrictPathfinderPenaltyAuxField > ( GetTraceRestrictAuxField ( item ) ) ) {
case TRPPAF_VALUE :
return TRPPPI_END ;
case TRPPAF_PRESET : {
uint16 index = GetTraceRestrictValue ( item ) ;
assert ( index < TRPPPI_END ) ;
return index ;
}
default :
NOT_REACHED ( ) ;
}
}
/** Common function for drawing an ordinary conditional instruction */
static void DrawInstructionStringConditionalCommon ( TraceRestrictItem item , const TraceRestrictTypePropertySet & properties )
{
assert ( GetTraceRestrictCondFlags ( item ) < = TRCF_OR ) ;
SetDParam ( 0 , _program_cond_type [ GetTraceRestrictCondFlags ( item ) ] ) ;
SetDParam ( 1 , GetTypeString ( GetTraceRestrictType ( item ) ) ) ;
SetDParam ( 2 , GetDropDownStringByValue ( GetCondOpDropDownListSet ( properties ) , GetTraceRestrictCondOp ( item ) ) ) ;
}
/** Common function for drawing an integer conditional instruction */
static void DrawInstructionStringConditionalIntegerCommon ( TraceRestrictItem item , const TraceRestrictTypePropertySet & properties )
{
DrawInstructionStringConditionalCommon ( item , properties ) ;
SetDParam ( 3 , GetTraceRestrictValue ( item ) ) ;
}
/** Common function for drawing an integer conditional instruction with an invalid value */
static void DrawInstructionStringConditionalInvalidValue ( TraceRestrictItem item , const TraceRestrictTypePropertySet & properties , StringID & instruction_string , bool selected )
{
instruction_string = STR_TRACE_RESTRICT_CONDITIONAL_UNDEFINED ;
DrawInstructionStringConditionalCommon ( item , properties ) ;
SetDParam ( 3 , selected ? STR_TRACE_RESTRICT_WHITE : STR_EMPTY ) ;
}
/**
* Draws an instruction in the programming GUI
* @ param prog The program ( may be NULL )
* @ param item The instruction to draw
* @ param index The instruction index
* @ param y Y position for drawing
* @ param selected True , if the order is selected
* @ param indent How many levels the instruction is indented
* @ param left Left border for text drawing
* @ param right Right border for text drawing
*/
static void DrawInstructionString ( const TraceRestrictProgram * prog , TraceRestrictItem item , int index , int y , bool selected , int indent , int left , int right )
{
StringID instruction_string = INVALID_STRING_ID ;
TraceRestrictTypePropertySet properties = GetTraceRestrictTypeProperties ( item ) ;
if ( IsTraceRestrictConditional ( item ) ) {
if ( GetTraceRestrictType ( item ) = = TRIT_COND_ENDIF ) {
if ( GetTraceRestrictCondFlags ( item ) & TRCF_ELSE ) {
instruction_string = STR_TRACE_RESTRICT_CONDITIONAL_ELSE ;
} else {
instruction_string = STR_TRACE_RESTRICT_CONDITIONAL_ENDIF ;
}
} else if ( GetTraceRestrictType ( item ) = = TRIT_COND_UNDEFINED ) {
instruction_string = STR_TRACE_RESTRICT_CONDITIONAL_COMPARE_UNDEFINED ;
SetDParam ( 0 , _program_cond_type [ GetTraceRestrictCondFlags ( item ) ] ) ;
SetDParam ( 1 , selected ? STR_TRACE_RESTRICT_WHITE : STR_EMPTY ) ;
} else {
switch ( properties . value_type ) {
case TRVT_INT :
instruction_string = STR_TRACE_RESTRICT_CONDITIONAL_COMPARE_INTEGER ;
DrawInstructionStringConditionalIntegerCommon ( item , properties ) ;
break ;
case TRVT_SPEED :
instruction_string = STR_TRACE_RESTRICT_CONDITIONAL_COMPARE_SPEED ;
DrawInstructionStringConditionalIntegerCommon ( item , properties ) ;
break ;
case TRVT_ORDER : {
switch ( static_cast < TraceRestrictOrderCondAuxField > ( GetTraceRestrictAuxField ( item ) ) ) {
case TROCAF_STATION :
if ( GetTraceRestrictValue ( item ) ! = INVALID_STATION ) {
instruction_string = STR_TRACE_RESTRICT_CONDITIONAL_ORDER_STATION ;
DrawInstructionStringConditionalIntegerCommon ( item , properties ) ;
} else {
// this is an invalid station, use a seperate string
DrawInstructionStringConditionalInvalidValue ( item , properties , instruction_string , selected ) ;
}
break ;
case TROCAF_WAYPOINT :
instruction_string = STR_TRACE_RESTRICT_CONDITIONAL_ORDER_WAYPOINT ;
DrawInstructionStringConditionalIntegerCommon ( item , properties ) ;
break ;
case TROCAF_DEPOT :
instruction_string = STR_TRACE_RESTRICT_CONDITIONAL_ORDER_DEPOT ;
DrawInstructionStringConditionalCommon ( item , properties ) ;
SetDParam ( 3 , VEH_TRAIN ) ;
SetDParam ( 4 , GetTraceRestrictValue ( item ) ) ;
break ;
default :
NOT_REACHED ( ) ;
break ;
}
break ;
}
case TRVT_CARGO_ID :
instruction_string = STR_TRACE_RESTRICT_CONDITIONAL_CARGO ;
assert ( GetTraceRestrictCondFlags ( item ) < = TRCF_OR ) ;
SetDParam ( 0 , _program_cond_type [ GetTraceRestrictCondFlags ( item ) ] ) ;
SetDParam ( 1 , GetDropDownStringByValue ( & _cargo_cond_ops , GetTraceRestrictCondOp ( item ) ) ) ;
SetDParam ( 2 , GetCargoStringByID ( GetTraceRestrictValue ( item ) ) ) ;
break ;
case TRVT_DIRECTION :
if ( GetTraceRestrictValue ( item ) > = TRDTSV_FRONT ) {
instruction_string = STR_TRACE_RESTRICT_CONDITIONAL_ENTRY_SIGNAL_FACE ;
} else {
instruction_string = STR_TRACE_RESTRICT_CONDITIONAL_ENTRY_DIRECTION ;
}
SetDParam ( 0 , _program_cond_type [ GetTraceRestrictCondFlags ( item ) ] ) ;
SetDParam ( 1 , GetDropDownStringByValue ( GetCondOpDropDownListSet ( properties ) , GetTraceRestrictCondOp ( item ) ) ) ;
SetDParam ( 2 , GetDropDownStringByValue ( & _direction_value , GetTraceRestrictValue ( item ) ) ) ;
break ;
case TRVT_TILE_INDEX : {
assert ( prog ! = NULL ) ;
assert ( GetTraceRestrictType ( item ) = = TRIT_COND_PBS_ENTRY_SIGNAL ) ;
TileIndex tile = * ( TraceRestrictProgram : : InstructionAt ( prog - > items , index - 1 ) + 1 ) ;
if ( tile = = INVALID_TILE ) {
DrawInstructionStringConditionalInvalidValue ( item , properties , instruction_string , selected ) ;
} else {
instruction_string = STR_TRACE_RESTRICT_CONDITIONAL_TILE_INDEX ;
SetDParam ( 0 , _program_cond_type [ GetTraceRestrictCondFlags ( item ) ] ) ;
SetDParam ( 1 , STR_TRACE_RESTRICT_VARIABLE_PBS_ENTRY_SIGNAL_LONG ) ;
SetDParam ( 2 , GetDropDownStringByValue ( GetCondOpDropDownListSet ( properties ) , GetTraceRestrictCondOp ( item ) ) ) ;
SetDParam ( 3 , TileX ( tile ) ) ;
SetDParam ( 4 , TileY ( tile ) ) ;
}
break ;
}
case TRVT_GROUP_INDEX : {
assert ( GetTraceRestrictCondFlags ( item ) < = TRCF_OR ) ;
SetDParam ( 0 , _program_cond_type [ GetTraceRestrictCondFlags ( item ) ] ) ;
SetDParam ( 1 , GetDropDownStringByValue ( GetCondOpDropDownListSet ( properties ) , GetTraceRestrictCondOp ( item ) ) ) ;
if ( GetTraceRestrictValue ( item ) = = INVALID_GROUP ) {
instruction_string = STR_TRACE_RESTRICT_CONDITIONAL_GROUP_STR ;
SetDParam ( 2 , STR_TRACE_RESTRICT_VARIABLE_UNDEFINED_RED ) ;
SetDParam ( 3 , selected ? STR_TRACE_RESTRICT_WHITE : STR_EMPTY ) ;
} else if ( GetTraceRestrictValue ( item ) = = DEFAULT_GROUP ) {
instruction_string = STR_TRACE_RESTRICT_CONDITIONAL_GROUP_STR ;
SetDParam ( 2 , STR_GROUP_DEFAULT_TRAINS ) ;
SetDParam ( 3 , selected ? STR_TRACE_RESTRICT_WHITE : STR_EMPTY ) ;
} else {
instruction_string = STR_TRACE_RESTRICT_CONDITIONAL_GROUP ;
SetDParam ( 2 , GetTraceRestrictValue ( item ) ) ;
}
break ;
}
case TRVT_OWNER : {
assert ( GetTraceRestrictCondFlags ( item ) < = TRCF_OR ) ;
CompanyID cid = static_cast < CompanyID > ( GetTraceRestrictValue ( item ) ) ;
if ( cid = = INVALID_COMPANY ) {
DrawInstructionStringConditionalInvalidValue ( item , properties , instruction_string , selected ) ;
} else {
instruction_string = STR_TRACE_RESTRICT_CONDITIONAL_OWNER ;
SetDParam ( 0 , _program_cond_type [ GetTraceRestrictCondFlags ( item ) ] ) ;
SetDParam ( 1 , GetTypeString ( GetTraceRestrictType ( item ) ) ) ;
SetDParam ( 2 , GetDropDownStringByValue ( GetCondOpDropDownListSet ( properties ) , GetTraceRestrictCondOp ( item ) ) ) ;
SetDParam ( 3 , cid ) ;
SetDParam ( 4 , cid ) ;
}
break ;
}
default :
NOT_REACHED ( ) ;
break ;
}
}
} else {
switch ( GetTraceRestrictType ( item ) ) {
case TRIT_NULL :
switch ( GetTraceRestrictValue ( item ) ) {
case TRNTSV_START :
instruction_string = STR_TRACE_RESTRICT_START ;
break ;
case TRNTSV_END :
instruction_string = STR_TRACE_RESTRICT_END ;
break ;
default :
NOT_REACHED ( ) ;
break ;
}
break ;
case TRIT_PF_DENY :
instruction_string = GetTraceRestrictValue ( item ) ? STR_TRACE_RESTRICT_PF_ALLOW_LONG : STR_TRACE_RESTRICT_PF_DENY ;
break ;
case TRIT_PF_PENALTY :
switch ( static_cast < TraceRestrictPathfinderPenaltyAuxField > ( GetTraceRestrictAuxField ( item ) ) ) {
case TRPPAF_VALUE :
instruction_string = STR_TRACE_RESTRICT_PF_PENALTY_ITEM ;
SetDParam ( 0 , GetTraceRestrictValue ( item ) ) ;
break ;
case TRPPAF_PRESET : {
instruction_string = STR_TRACE_RESTRICT_PF_PENALTY_ITEM_PRESET ;
uint16 index = GetTraceRestrictValue ( item ) ;
assert ( index < TRPPPI_END ) ;
SetDParam ( 0 , _pf_penalty_dropdown_str [ index ] ) ;
break ;
}
default :
NOT_REACHED ( ) ;
}
break ;
case TRIT_RESERVE_THROUGH :
instruction_string = GetTraceRestrictValue ( item ) ? STR_TRACE_RESTRICT_RESERVE_THROUGH_CANCEL : STR_TRACE_RESTRICT_RESERVE_THROUGH ;
break ;
case TRIT_LONG_RESERVE :
instruction_string = GetTraceRestrictValue ( item ) ? STR_TRACE_RESTRICT_LONG_RESERVE_CANCEL : STR_TRACE_RESTRICT_LONG_RESERVE ;
break ;
default :
NOT_REACHED ( ) ;
break ;
}
}
DrawString ( left + indent * 16 , right , y , instruction_string , selected ? TC_WHITE : TC_BLACK ) ;
}
/** Main GUI window class */
class TraceRestrictWindow : public Window {
TileIndex tile ; ///< tile this window is for
Track track ; ///< track this window is for
int selected_instruction ; ///< selected instruction index, this is offset by one due to the display of the "start" item
Scrollbar * vscroll ; ///< scrollbar widget
std : : map < int , const TraceRestrictDropDownListSet * > drop_down_list_mapping ; ///< mapping of widget IDs to drop down list sets
bool value_drop_down_is_company ; ///< TR_WIDGET_VALUE_DROPDOWN is a company list
TraceRestrictItem expecting_inserted_item ; ///< set to instruction when performing an instruction insertion, used to handle selection update on insertion
int current_placement_widget ; ///< which widget has a SetObjectToPlaceWnd, if any
public :
TraceRestrictWindow ( WindowDesc * desc , TileIndex tile , Track track )
: Window ( desc )
{
this - > tile = tile ;
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 ) ;
this - > FinishInitNested ( MakeTraceRestrictRefId ( tile , track ) ) ;
this - > ReloadProgramme ( ) ;
}
virtual void OnClick ( Point pt , int widget , int click_count ) OVERRIDE
{
switch ( widget ) {
case TR_WIDGET_INSTRUCTION_LIST : {
int sel = this - > GetItemIndexFromPt ( pt . y ) ;
if ( _ctrl_pressed ) {
// scroll to target (for stations, waypoints, depots)
if ( sel = = - 1 ) return ;
TraceRestrictItem item = this - > GetItem ( this - > GetProgram ( ) , sel ) ;
if ( GetTraceRestrictTypeProperties ( item ) . value_type = = TRVT_ORDER ) {
switch ( static_cast < TraceRestrictOrderCondAuxField > ( GetTraceRestrictAuxField ( item ) ) ) {
case TROCAF_STATION :
case TROCAF_WAYPOINT : {
BaseStation * st = BaseStation : : GetIfValid ( GetTraceRestrictValue ( item ) ) ;
if ( st ) {
ScrollMainWindowToTile ( st - > xy ) ;
}
break ;
}
case TROCAF_DEPOT : {
Depot * depot = Depot : : GetIfValid ( GetTraceRestrictValue ( item ) ) ;
if ( depot ) {
ScrollMainWindowToTile ( depot - > xy ) ;
}
break ;
}
}
}
return ;
}
this - > DeleteChildWindows ( ) ;
HideDropDownMenu ( this ) ;
if ( sel = = - 1 | | this - > GetOwner ( ) ! = _local_company ) {
// Deselect
this - > selected_instruction = - 1 ;
} else {
this - > selected_instruction = sel ;
}
this - > expecting_inserted_item = static_cast < TraceRestrictItem > ( 0 ) ;
this - > UpdateButtonState ( ) ;
break ;
}
case TR_WIDGET_INSERT : {
if ( this - > GetOwner ( ) ! = _local_company | | this - > selected_instruction < 1 ) {
return ;
}
uint32 disabled = _program_insert_or_if_hide_mask ;
TraceRestrictItem item = this - > GetSelected ( ) ;
if ( GetTraceRestrictType ( item ) = = TRIT_COND_ENDIF | |
( IsTraceRestrictConditional ( item ) & & GetTraceRestrictCondFlags ( item ) ! = 0 ) ) {
// this is either: an else/or if, an else, or an end if
// try to include else if, else in insertion list
if ( ! ElseInsertionDryRun ( false ) ) disabled | = _program_insert_else_hide_mask ;
if ( ! ElseIfInsertionDryRun ( false ) ) disabled | = _program_insert_else_if_hide_mask ;
} else {
// can't insert else/end if here
disabled | = _program_insert_else_hide_mask | _program_insert_else_if_hide_mask ;
}
if ( this - > selected_instruction > 1 ) {
TraceRestrictItem prev_item = this - > GetItem ( this - > GetProgram ( ) , this - > selected_instruction - 1 ) ;
if ( IsTraceRestrictConditional ( prev_item ) & & GetTraceRestrictType ( prev_item ) ! = TRIT_COND_ENDIF ) {
// previous item is either: an if, or an else/or if
// else if has same validation rules as or if, use it instead of creating another test function
if ( ElseIfInsertionDryRun ( false ) ) disabled & = ~ _program_insert_or_if_hide_mask ;
}
}
this - > ShowDropDownListWithValue ( & _program_insert , 0 , true , TR_WIDGET_INSERT , disabled , 0 , 0 ) ;
break ;
}
case TR_WIDGET_REMOVE : {
TraceRestrictItem item = this - > GetSelected ( ) ;
if ( this - > GetOwner ( ) ! = _local_company | | item = = 0 ) {
return ;
}
TraceRestrictDoCommandP ( tile , track , TRDCT_REMOVE_ITEM , this - > selected_instruction - 1 , 0 , STR_TRACE_RESTRICT_ERROR_CAN_T_REMOVE_ITEM ) ;
break ;
}
case TR_WIDGET_CONDFLAGS : {
TraceRestrictItem item = this - > GetSelected ( ) ;
if ( this - > GetOwner ( ) ! = _local_company | | item = = 0 ) {
return ;
}
CondFlagsDropDownType type ;
if ( GetTraceRestrictType ( item ) = = TRIT_COND_ENDIF ) {
if ( GetTraceRestrictCondFlags ( item ) = = 0 ) return ; // end if
type = CFDDT_ELSE ;
} else if ( IsTraceRestrictConditional ( item ) & & GetTraceRestrictCondFlags ( item ) ! = 0 ) {
type = static_cast < CondFlagsDropDownType > ( GetTraceRestrictCondFlags ( item ) ) ;
} else {
return ;
}
uint32 disabled = 0 ;
if ( ! ElseInsertionDryRun ( true ) ) disabled | = _condflags_dropdown_else_hide_mask ;
if ( ! ElseIfInsertionDryRun ( true ) ) disabled | = _condflags_dropdown_else_if_hide_mask ;
this - > ShowDropDownListWithValue ( & _condflags_dropdown , type , false , TR_WIDGET_CONDFLAGS , disabled , 0 , 0 ) ;
break ;
}
case TR_WIDGET_TYPE_COND :
case TR_WIDGET_TYPE_NONCOND : {
TraceRestrictItem item = this - > GetSelected ( ) ;
TraceRestrictItemType type = GetTraceRestrictType ( item ) ;
if ( type ! = TRIT_NULL ) {
this - > ShowDropDownListWithValue ( GetTypeDropDownListSet ( type ) , type , false , widget , 0 , 0 , 0 ) ;
}
break ;
}
case TR_WIDGET_COMPARATOR : {
TraceRestrictItem item = this - > GetSelected ( ) ;
const TraceRestrictDropDownListSet * list_set = GetCondOpDropDownListSet ( GetTraceRestrictTypeProperties ( item ) ) ;
if ( list_set ) {
this - > ShowDropDownListWithValue ( list_set , GetTraceRestrictCondOp ( item ) , false , TR_WIDGET_COMPARATOR , 0 , 0 , 0 ) ;
}
break ;
}
case TR_WIDGET_VALUE_INT : {
TraceRestrictItem item = this - > GetSelected ( ) ;
TraceRestrictValueType type = GetTraceRestrictTypeProperties ( item ) . value_type ;
if ( IsIntegerValueType ( type ) ) {
SetDParam ( 0 , ConvertIntegerValue ( type , GetTraceRestrictValue ( item ) , true ) ) ;
ShowQueryString ( STR_JUST_INT , STR_TRACE_RESTRICT_VALUE_CAPTION , 10 , this , CS_NUMERAL , QSF_NONE ) ;
}
break ;
}
case TR_WIDGET_VALUE_DROPDOWN : {
TraceRestrictItem item = this - > GetSelected ( ) ;
switch ( GetTraceRestrictTypeProperties ( item ) . value_type ) {
case TRVT_DENY :
this - > ShowDropDownListWithValue ( & _deny_value , GetTraceRestrictValue ( item ) , false , TR_WIDGET_VALUE_DROPDOWN , 0 , 0 , 0 ) ;
break ;
case TRVT_CARGO_ID :
this - > ShowDropDownListWithValue ( GetSortedCargoTypeDropDownListSet ( ) , GetTraceRestrictValue ( item ) , true , TR_WIDGET_VALUE_DROPDOWN , 0 , 0 , 0 ) ; // current cargo is permitted to not be in list
break ;
case TRVT_DIRECTION :
this - > ShowDropDownListWithValue ( & _direction_value , GetTraceRestrictValue ( item ) , false , TR_WIDGET_VALUE_DROPDOWN , 0 , 0 , 0 ) ;
break ;
case TRVT_PF_PENALTY :
this - > ShowDropDownListWithValue ( & _pf_penalty_dropdown , GetPathfinderPenaltyDropdownIndex ( item ) , false , TR_WIDGET_VALUE_DROPDOWN , 0 , 0 , 0 ) ;
break ;
case TRVT_RESERVE_THROUGH :
this - > ShowDropDownListWithValue ( & _reserve_through_value , GetTraceRestrictValue ( item ) , false , TR_WIDGET_VALUE_DROPDOWN , 0 , 0 , 0 ) ;
break ;
case TRVT_LONG_RESERVE :
this - > ShowDropDownListWithValue ( & _long_reserve_value , GetTraceRestrictValue ( item ) , false , TR_WIDGET_VALUE_DROPDOWN , 0 , 0 , 0 ) ;
break ;
case TRVT_GROUP_INDEX : {
int selected ;
DropDownList * dlist = GetGroupDropDownList ( this - > GetOwner ( ) , GetTraceRestrictValue ( item ) , selected ) ;
ShowDropDownList ( this , dlist , selected , TR_WIDGET_VALUE_DROPDOWN ) ;
break ;
}
case TRVT_OWNER :
this - > ShowCompanyDropDownListWithValue ( static_cast < CompanyID > ( GetTraceRestrictValue ( item ) ) , false , TR_WIDGET_VALUE_DROPDOWN ) ;
break ;
default :
break ;
}
break ;
}
case TR_WIDGET_VALUE_DEST : {
SetObjectToPlaceAction ( widget , ANIMCURSOR_PICKSTATION ) ;
break ;
}
case TR_WIDGET_VALUE_SIGNAL : {
SetObjectToPlaceAction ( widget , ANIMCURSOR_BUILDSIGNALS ) ;
break ;
}
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 :
SetObjectToPlaceAction ( widget , ANIMCURSOR_BUILDSIGNALS ) ;
break ;
case TR_WIDGET_UNSHARE : {
TraceRestrictProgMgmtDoCommandP ( tile , track , TRDCT_PROG_UNSHARE , STR_TRACE_RESTRICT_ERROR_CAN_T_UNSHARE_PROGRAM ) ;
break ;
}
}
}
virtual void OnQueryTextFinished ( char * str ) OVERRIDE
{
if ( StrEmpty ( str ) ) {
return ;
}
TraceRestrictItem item = GetSelected ( ) ;
TraceRestrictValueType type = GetTraceRestrictTypeProperties ( item ) . value_type ;
if ( ! IsIntegerValueType ( type ) & & type ! = TRVT_PF_PENALTY ) {
return ;
}
uint value = ConvertIntegerValue ( type , atoi ( str ) , false ) ;
if ( value > = ( 1 < < TRIFA_VALUE_COUNT ) ) {
SetDParam ( 0 , ConvertIntegerValue ( type , ( 1 < < TRIFA_VALUE_COUNT ) - 1 , true ) ) ;
ShowErrorMessage ( STR_TRACE_RESTRICT_ERROR_VALUE_TOO_LARGE , STR_EMPTY , WL_INFO ) ;
return ;
}
if ( type = = TRVT_PF_PENALTY ) {
SetTraceRestrictAuxField ( item , TRPPAF_VALUE ) ;
}
SetTraceRestrictValue ( item , value ) ;
TraceRestrictDoCommandP ( tile , track , TRDCT_MODIFY_ITEM , this - > selected_instruction - 1 , item , STR_TRACE_RESTRICT_ERROR_CAN_T_MODIFY_ITEM ) ;
}
virtual void OnDropdownSelect ( int widget , int index ) OVERRIDE
{
TraceRestrictItem item = GetSelected ( ) ;
if ( item = = 0 | | index < 0 | | this - > selected_instruction < 1 ) {
return ;
}
if ( widget = = TR_WIDGET_VALUE_DROPDOWN & & ( this - > value_drop_down_is_company | | GetTraceRestrictTypeProperties ( item ) . value_type = = TRVT_GROUP_INDEX ) ) {
// this is a special company drop-down or group-index drop-down
SetTraceRestrictValue ( item , index ) ;
TraceRestrictDoCommandP ( this - > tile , this - > track , TRDCT_MODIFY_ITEM , this - > selected_instruction - 1 , item , STR_TRACE_RESTRICT_ERROR_CAN_T_MODIFY_ITEM ) ;
return ;
}
const TraceRestrictDropDownListSet * list_set = this - > drop_down_list_mapping [ widget ] ;
if ( ! list_set ) {
return ;
}
uint value = list_set - > value_array [ index ] ;
switch ( widget ) {
case TR_WIDGET_INSERT : {
TraceRestrictItem insert_item = 0 ;
TraceRestrictCondFlags cond_flags = static_cast < TraceRestrictCondFlags > ( value > > 16 ) ;
value & = 0xFFFF ;
SetTraceRestrictTypeAndNormalise ( insert_item , static_cast < TraceRestrictItemType > ( value ) ) ;
SetTraceRestrictCondFlags ( insert_item , cond_flags ) ; // this needs to happen after calling SetTraceRestrictTypeAndNormalise
this - > expecting_inserted_item = insert_item ;
TraceRestrictDoCommandP ( this - > tile , this - > track , TRDCT_INSERT_ITEM , this - > selected_instruction - 1 , insert_item , STR_TRACE_RESTRICT_ERROR_CAN_T_INSERT_ITEM ) ;
break ;
}
case TR_WIDGET_CONDFLAGS : {
CondFlagsDropDownType cond_type = static_cast < CondFlagsDropDownType > ( value ) ;
if ( cond_type = = CFDDT_ELSE ) {
SetTraceRestrictTypeAndNormalise ( item , TRIT_COND_ENDIF ) ;
SetTraceRestrictCondFlags ( item , TRCF_ELSE ) ;
} else {
if ( GetTraceRestrictType ( item ) = = TRIT_COND_ENDIF ) {
// item is currently an else, convert to else/or if
SetTraceRestrictTypeAndNormalise ( item , TRIT_COND_UNDEFINED ) ;
}
SetTraceRestrictCondFlags ( item , static_cast < TraceRestrictCondFlags > ( cond_type ) ) ;
}
TraceRestrictDoCommandP ( this - > tile , this - > track , TRDCT_MODIFY_ITEM , this - > selected_instruction - 1 , item , STR_TRACE_RESTRICT_ERROR_CAN_T_MODIFY_ITEM ) ;
break ;
}
case TR_WIDGET_TYPE_COND :
case TR_WIDGET_TYPE_NONCOND : {
SetTraceRestrictTypeAndNormalise ( item , static_cast < TraceRestrictItemType > ( value ) ) ;
if ( GetTraceRestrictType ( item ) = = TRIT_COND_LAST_STATION & & GetTraceRestrictAuxField ( item ) ! = TROCAF_STATION ) {
// if changing type from another order type to last visited station, reset value if not currently a station
SetTraceRestrictValueDefault ( item , TRVT_ORDER ) ;
}
TraceRestrictDoCommandP ( this - > tile , this - > track , TRDCT_MODIFY_ITEM , this - > selected_instruction - 1 , item , STR_TRACE_RESTRICT_ERROR_CAN_T_MODIFY_ITEM ) ;
break ;
}
case TR_WIDGET_COMPARATOR : {
SetTraceRestrictCondOp ( item , static_cast < TraceRestrictCondOp > ( value ) ) ;
TraceRestrictDoCommandP ( this - > tile , this - > track , TRDCT_MODIFY_ITEM , this - > selected_instruction - 1 , item , STR_TRACE_RESTRICT_ERROR_CAN_T_MODIFY_ITEM ) ;
break ;
}
case TR_WIDGET_VALUE_DROPDOWN : {
if ( GetTraceRestrictTypeProperties ( item ) . value_type = = TRVT_PF_PENALTY ) {
if ( value = = TRPPPI_END ) {
uint16 penalty_value ;
if ( GetTraceRestrictAuxField ( item ) = = TRPPAF_PRESET ) {
penalty_value = _tracerestrict_pathfinder_penalty_preset_values [ GetTraceRestrictValue ( item ) ] ;
} else {
penalty_value = GetTraceRestrictValue ( item ) ;
}
SetDParam ( 0 , penalty_value ) ;
ShowQueryString ( STR_JUST_INT , STR_TRACE_RESTRICT_VALUE_CAPTION , 10 , this , CS_NUMERAL , QSF_NONE ) ;
return ;
} else {
SetTraceRestrictValue ( item , value ) ;
SetTraceRestrictAuxField ( item , TRPPAF_PRESET ) ;
}
} else {
SetTraceRestrictValue ( item , value ) ;
}
TraceRestrictDoCommandP ( this - > tile , this - > track , TRDCT_MODIFY_ITEM , this - > selected_instruction - 1 , item , STR_TRACE_RESTRICT_ERROR_CAN_T_MODIFY_ITEM ) ;
break ;
}
}
}
virtual void OnPlaceObject ( Point pt , TileIndex tile ) OVERRIDE
{
int widget = this - > current_placement_widget ;
this - > current_placement_widget = - 1 ;
this - > RaiseButtons ( ) ;
ResetObjectToPlace ( ) ;
if ( widget < 0 ) {
return ;
}
switch ( widget ) {
case TR_WIDGET_COPY :
OnPlaceObjectSignal ( pt , tile , widget , STR_TRACE_RESTRICT_ERROR_CAN_T_COPY_PROGRAM ) ;
break ;
case TR_WIDGET_SHARE :
OnPlaceObjectSignal ( pt , tile , widget , STR_TRACE_RESTRICT_ERROR_CAN_T_SHARE_PROGRAM ) ;
break ;
case TR_WIDGET_VALUE_DEST :
OnPlaceObjectDestination ( pt , tile , widget , STR_TRACE_RESTRICT_ERROR_CAN_T_MODIFY_ITEM ) ;
break ;
case TR_WIDGET_VALUE_SIGNAL :
OnPlaceObjectSignalTileValue ( pt , tile , widget , STR_TRACE_RESTRICT_ERROR_CAN_T_MODIFY_ITEM ) ;
break ;
default :
NOT_REACHED ( ) ;
break ;
}
}
/**
* Common OnPlaceObject handler for program management actions which involve clicking on a signal
*/
void OnPlaceObjectSignal ( Point pt , TileIndex source_tile , int widget , int error_message )
{
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 ;
}
}
/**
* Common OnPlaceObject handler for instruction value modification actions which involve selecting an order target
*/
void OnPlaceObjectDestination ( Point pt , TileIndex tile , int widget , int error_message )
{
TraceRestrictItem item = GetSelected ( ) ;
if ( GetTraceRestrictTypeProperties ( item ) . value_type ! = TRVT_ORDER ) return ;
bool stations_only = ( GetTraceRestrictType ( item ) = = TRIT_COND_LAST_STATION ) ;
if ( IsDepotTypeTile ( tile , TRANSPORT_RAIL ) ) {
if ( stations_only ) return ;
SetTraceRestrictValue ( item , GetDepotIndex ( tile ) ) ;
SetTraceRestrictAuxField ( item , TROCAF_DEPOT ) ;
} else if ( IsRailWaypointTile ( tile ) ) {
if ( stations_only ) return ;
SetTraceRestrictValue ( item , GetStationIndex ( tile ) ) ;
SetTraceRestrictAuxField ( item , TROCAF_WAYPOINT ) ;
} else if ( IsTileType ( tile , MP_STATION ) ) {
StationID st_index = GetStationIndex ( tile ) ;
const Station * st = Station : : Get ( st_index ) ;
if ( st - > facilities & FACIL_TRAIN ) {
SetTraceRestrictValue ( item , st_index ) ;
SetTraceRestrictAuxField ( item , TROCAF_STATION ) ;
} else {
return ;
}
} else {
return ;
}
if ( ! IsTileOwner ( tile , _local_company ) ) {
ShowErrorMessage ( error_message , STR_ERROR_AREA_IS_OWNED_BY_ANOTHER , WL_INFO ) ;
return ;
}
TraceRestrictDoCommandP ( this - > tile , this - > track , TRDCT_MODIFY_ITEM , this - > selected_instruction - 1 , item , STR_TRACE_RESTRICT_ERROR_CAN_T_MODIFY_ITEM ) ;
}
/**
* Common OnPlaceObject handler for instruction value modification actions which involve selecting a signal tile value
*/
void OnPlaceObjectSignalTileValue ( Point pt , TileIndex tile , int widget , int error_message )
{
TraceRestrictItem item = GetSelected ( ) ;
if ( GetTraceRestrictTypeProperties ( item ) . value_type ! = TRVT_TILE_INDEX ) return ;
if ( ! IsPlainRailTile ( tile ) ) {
ShowErrorMessage ( error_message , STR_ERROR_THERE_IS_NO_RAILROAD_TRACK , WL_INFO ) ;
return ;
}
if ( GetPresentSignals ( tile ) = = 0 ) {
ShowErrorMessage ( error_message , STR_ERROR_THERE_ARE_NO_SIGNALS , WL_INFO ) ;
return ;
}
if ( ! IsTileOwner ( tile , _local_company ) ) {
ShowErrorMessage ( error_message , STR_ERROR_AREA_IS_OWNED_BY_ANOTHER , WL_INFO ) ;
return ;
}
TraceRestrictDoCommandP ( this - > tile , this - > track , TRDCT_MODIFY_DUAL_ITEM , this - > selected_instruction - 1 , tile , STR_TRACE_RESTRICT_ERROR_CAN_T_MODIFY_ITEM ) ;
}
virtual void OnPlaceObjectAbort ( ) OVERRIDE
{
this - > RaiseButtons ( ) ;
this - > current_placement_widget = - 1 ;
}
virtual void UpdateWidgetSize ( int widget , Dimension * size , const Dimension & padding , Dimension * fill , Dimension * resize ) OVERRIDE
{
switch ( widget ) {
case TR_WIDGET_INSTRUCTION_LIST :
resize - > height = FONT_HEIGHT_NORMAL ;
size - > height = 6 * resize - > height + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM ;
break ;
}
}
virtual void OnResize ( ) OVERRIDE
{
/* Update the scroll bar */
this - > vscroll - > SetCapacityFromWidget ( this , TR_WIDGET_INSTRUCTION_LIST ) ;
}
virtual void OnPaint ( ) OVERRIDE
{
this - > DrawWidgets ( ) ;
}
virtual void DrawWidget ( const Rect & r , int widget ) const OVERRIDE
{
if ( widget ! = TR_WIDGET_INSTRUCTION_LIST ) return ;
int y = r . top + WD_FRAMERECT_TOP ;
int line_height = this - > GetWidget < NWidgetBase > ( TR_WIDGET_INSTRUCTION_LIST ) - > resize_y ;
int scroll_position = this - > vscroll - > GetPosition ( ) ;
// prog may be NULL
const TraceRestrictProgram * prog = this - > GetProgram ( ) ;
int count = this - > GetItemCount ( prog ) ;
uint indent = 1 ;
for ( int i = 0 ; i < count ; i + + ) {
TraceRestrictItem item = this - > GetItem ( prog , i ) ;
uint this_indent = indent ;
if ( IsTraceRestrictConditional ( item ) ) {
if ( GetTraceRestrictCondFlags ( item ) & ( TRCF_ELSE | TRCF_OR ) ) {
this_indent - - ;
} else if ( GetTraceRestrictType ( item ) = = TRIT_COND_ENDIF ) {
indent - - ;
this_indent - - ;
} else {
indent + + ;
}
} else if ( GetTraceRestrictType ( item ) = = TRIT_NULL ) {
this_indent = 0 ;
}
if ( i > = scroll_position & & this - > vscroll - > IsVisible ( i ) ) {
DrawInstructionString ( prog , item , i , y , i = = this - > selected_instruction , this_indent , r . left + WD_FRAMETEXT_LEFT , r . right - WD_FRAMETEXT_RIGHT ) ;
y + = line_height ;
}
}
}
virtual void OnInvalidateData ( int data , bool gui_scope ) OVERRIDE
{
if ( gui_scope ) {
this - > ReloadProgramme ( ) ;
}
}
virtual void SetStringParameters ( int widget ) const OVERRIDE
{
switch ( widget ) {
case TR_WIDGET_VALUE_INT : {
SetDParam ( 0 , 0 ) ;
TraceRestrictItem item = this - > GetSelected ( ) ;
TraceRestrictValueType type = GetTraceRestrictTypeProperties ( item ) . value_type ;
if ( IsIntegerValueType ( type ) ) {
SetDParam ( 0 , ConvertIntegerValue ( type , GetTraceRestrictValue ( item ) , true ) ) ;
}
break ;
}
case TR_WIDGET_CAPTION : {
const TraceRestrictProgram * prog = this - > GetProgram ( ) ;
if ( prog ) {
SetDParam ( 0 , prog - > refcount ) ;
} else {
SetDParam ( 0 , 1 ) ;
}
break ;
}
case TR_WIDGET_VALUE_DROPDOWN : {
TraceRestrictItem item = this - > GetSelected ( ) ;
if ( ( GetTraceRestrictTypeProperties ( item ) . value_type = = TRVT_PF_PENALTY & &
GetTraceRestrictAuxField ( item ) = = TRPPAF_VALUE )
| | GetTraceRestrictTypeProperties ( item ) . value_type = = TRVT_GROUP_INDEX ) {
SetDParam ( 0 , GetTraceRestrictValue ( item ) ) ;
}
break ;
}
}
}
private :
/**
* Helper function to make start and end instructions ( these are not stored in the actual program )
*/
TraceRestrictItem MakeSpecialItem ( TraceRestrictNullTypeSpecialValue value ) const
{
TraceRestrictItem item = 0 ;
SetTraceRestrictType ( item , TRIT_NULL ) ;
SetTraceRestrictValue ( item , value ) ;
return item ;
}
/**
* Get item count of program , including start and end markers
*/
int GetItemCount ( const TraceRestrictProgram * prog ) const
{
if ( prog ) {
return 2 + prog - > GetInstructionCount ( ) ;
} else {
return 2 ;
}
}
/**
* Get current program
* This may return NULL if no program currently exists
*/
const TraceRestrictProgram * GetProgram ( ) const
{
return GetTraceRestrictProgram ( MakeTraceRestrictRefId ( tile , track ) , false ) ;
}
/**
* Get instruction at @ p index in program @ p prog
* This correctly handles start / end markers , offsets , etc .
* This returns a 0 instruction if out of bounds
* @ p prog may be NULL
*/
TraceRestrictItem GetItem ( const TraceRestrictProgram * prog , int index ) const
{
if ( index < 0 ) {
return 0 ;
}
if ( index = = 0 ) {
return MakeSpecialItem ( TRNTSV_START ) ;
}
if ( prog ) {
size_t instruction_count = prog - > GetInstructionCount ( ) ;
if ( static_cast < size_t > ( index ) = = instruction_count + 1 ) {
return MakeSpecialItem ( TRNTSV_END ) ;
}
if ( static_cast < size_t > ( index ) > instruction_count + 1 ) {
return 0 ;
}
return prog - > items [ prog - > InstructionOffsetToArrayOffset ( index - 1 ) ] ;
} else {
// No program defined, this is equivalent to an empty program
if ( index = = 1 ) {
return MakeSpecialItem ( TRNTSV_END ) ;
} else {
return 0 ;
}
}
}
/**
* Get selected instruction , or a zero instruction
*/
TraceRestrictItem GetSelected ( ) const
{
return this - > GetItem ( this - > GetProgram ( ) , this - > selected_instruction ) ;
}
/**
* Get owner of the signal tile this window is pointing at
*/
Owner GetOwner ( )
{
return GetTileOwner ( this - > tile ) ;
}
/**
* Return item index from point in instruction list widget
*/
int GetItemIndexFromPt ( int y )
{
NWidgetBase * nwid = this - > GetWidget < NWidgetBase > ( TR_WIDGET_INSTRUCTION_LIST ) ;
int sel = ( y - nwid - > pos_y - WD_FRAMERECT_TOP ) / nwid - > resize_y ; // Selected line
if ( ( uint ) sel > = this - > vscroll - > GetCapacity ( ) ) return - 1 ;
sel + = this - > vscroll - > GetPosition ( ) ;
return ( sel < this - > GetItemCount ( this - > GetProgram ( ) ) & & sel > = 0 ) ? sel : - 1 ;
}
/**
* Reload details of program , and adjust length / selection position as necessary
*/
void ReloadProgramme ( )
{
const TraceRestrictProgram * prog = this - > GetProgram ( ) ;
if ( this - > vscroll - > GetCount ( ) ! = this - > GetItemCount ( prog ) ) {
// program length has changed
if ( this - > GetItemCount ( prog ) < this - > vscroll - > GetCount ( ) | |
this - > GetItem ( prog , this - > selected_instruction ) ! = this - > expecting_inserted_item ) {
// length has shrunk or if we weren't expecting an insertion, deselect
this - > selected_instruction = - 1 ;
}
this - > expecting_inserted_item = static_cast < TraceRestrictItem > ( 0 ) ;
// update scrollbar size
this - > vscroll - > SetCount ( this - > GetItemCount ( prog ) ) ;
}
this - > UpdateButtonState ( ) ;
}
/**
* Update button states , text values , etc .
*/
void UpdateButtonState ( )
{
this - > RaiseWidget ( TR_WIDGET_INSERT ) ;
this - > RaiseWidget ( TR_WIDGET_REMOVE ) ;
this - > RaiseWidget ( TR_WIDGET_TYPE_COND ) ;
this - > RaiseWidget ( TR_WIDGET_TYPE_NONCOND ) ;
this - > RaiseWidget ( TR_WIDGET_CONDFLAGS ) ;
this - > RaiseWidget ( TR_WIDGET_COMPARATOR ) ;
this - > RaiseWidget ( TR_WIDGET_VALUE_INT ) ;
this - > RaiseWidget ( TR_WIDGET_VALUE_DROPDOWN ) ;
this - > RaiseWidget ( TR_WIDGET_VALUE_DEST ) ;
this - > RaiseWidget ( TR_WIDGET_VALUE_SIGNAL ) ;
NWidgetStacked * left_2_sel = this - > GetWidget < NWidgetStacked > ( TR_WIDGET_SEL_TOP_LEFT_2 ) ;
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_COND ) ;
this - > DisableWidget ( TR_WIDGET_TYPE_NONCOND ) ;
this - > DisableWidget ( TR_WIDGET_CONDFLAGS ) ;
this - > DisableWidget ( TR_WIDGET_COMPARATOR ) ;
this - > DisableWidget ( TR_WIDGET_VALUE_INT ) ;
this - > DisableWidget ( TR_WIDGET_VALUE_DROPDOWN ) ;
this - > DisableWidget ( TR_WIDGET_VALUE_DEST ) ;
this - > DisableWidget ( TR_WIDGET_VALUE_SIGNAL ) ;
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_L2 ) ;
this - > DisableWidget ( TR_WIDGET_BLANK_L ) ;
this - > DisableWidget ( TR_WIDGET_BLANK_M ) ;
this - > DisableWidget ( TR_WIDGET_BLANK_R ) ;
left_2_sel - > SetDisplayedPlane ( DPL2_BLANK ) ;
left_sel - > SetDisplayedPlane ( DPL_BLANK ) ;
middle_sel - > SetDisplayedPlane ( DPM_BLANK ) ;
right_sel - > SetDisplayedPlane ( DPR_BLANK ) ;
share_sel - > SetDisplayedPlane ( DPS_SHARE ) ;
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 ;
}
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 ) ) {
case TRNTSV_START :
break ;
case TRNTSV_END :
this - > EnableWidget ( TR_WIDGET_INSERT ) ;
break ;
default :
NOT_REACHED ( ) ;
break ;
}
} else if ( GetTraceRestrictType ( item ) = = TRIT_COND_ENDIF ) {
this - > EnableWidget ( TR_WIDGET_INSERT ) ;
if ( GetTraceRestrictCondFlags ( item ) ! = 0 ) {
// this is not an end if, it must be an else, enable removing
this - > EnableWidget ( TR_WIDGET_REMOVE ) ;
// setup condflags dropdown to show else
left_2_sel - > SetDisplayedPlane ( DPL2_CONDFLAGS ) ;
this - > EnableWidget ( TR_WIDGET_CONDFLAGS ) ;
this - > GetWidget < NWidgetCore > ( TR_WIDGET_CONDFLAGS ) - > widget_data = STR_TRACE_RESTRICT_CONDITIONAL_ELSE ;
}
} else {
TraceRestrictTypePropertySet properties = GetTraceRestrictTypeProperties ( item ) ;
int type_widget ;
if ( IsTraceRestrictConditional ( item ) ) {
// note that else and end if items are not handled here, they are handled above
left_2_sel - > SetDisplayedPlane ( DPL2_CONDFLAGS ) ;
left_sel - > SetDisplayedPlane ( DPL_TYPE ) ;
type_widget = TR_WIDGET_TYPE_COND ;
// setup condflags dropdown box
left_2_sel - > SetDisplayedPlane ( DPL2_CONDFLAGS ) ;
switch ( GetTraceRestrictCondFlags ( item ) ) {
case TRCF_DEFAULT : // opening if, leave disabled
this - > GetWidget < NWidgetCore > ( TR_WIDGET_CONDFLAGS ) - > widget_data = STR_TRACE_RESTRICT_CONDITIONAL_IF ;
break ;
case TRCF_ELSE : // else-if
this - > GetWidget < NWidgetCore > ( TR_WIDGET_CONDFLAGS ) - > widget_data = STR_TRACE_RESTRICT_CONDITIONAL_ELIF ;
this - > EnableWidget ( TR_WIDGET_CONDFLAGS ) ;
break ;
case TRCF_OR : // or-if
this - > GetWidget < NWidgetCore > ( TR_WIDGET_CONDFLAGS ) - > widget_data = STR_TRACE_RESTRICT_CONDITIONAL_ORIF ;
this - > EnableWidget ( TR_WIDGET_CONDFLAGS ) ;
break ;
default :
NOT_REACHED ( ) ;
break ;
}
} else {
left_2_sel - > SetDisplayedPlane ( DPL2_TYPE ) ;
type_widget = TR_WIDGET_TYPE_NONCOND ;
}
this - > EnableWidget ( type_widget ) ;
this - > GetWidget < NWidgetCore > ( type_widget ) - > widget_data =
GetTypeString ( GetTraceRestrictType ( item ) ) ;
if ( properties . cond_type = = TRCOT_BINARY | | properties . cond_type = = TRCOT_ALL ) {
middle_sel - > SetDisplayedPlane ( DPM_COMPARATOR ) ;
this - > EnableWidget ( TR_WIDGET_COMPARATOR ) ;
const TraceRestrictDropDownListSet * list_set = GetCondOpDropDownListSet ( properties ) ;
if ( list_set ) {
this - > GetWidget < NWidgetCore > ( TR_WIDGET_COMPARATOR ) - > widget_data =
GetDropDownStringByValue ( list_set , GetTraceRestrictCondOp ( item ) ) ;
}
}
if ( IsIntegerValueType ( properties . value_type ) ) {
right_sel - > SetDisplayedPlane ( DPR_VALUE_INT ) ;
this - > EnableWidget ( TR_WIDGET_VALUE_INT ) ;
} else {
switch ( properties . value_type ) {
case TRVT_DENY :
right_sel - > SetDisplayedPlane ( DPR_VALUE_DROPDOWN ) ;
this - > EnableWidget ( TR_WIDGET_VALUE_DROPDOWN ) ;
this - > GetWidget < NWidgetCore > ( TR_WIDGET_VALUE_DROPDOWN ) - > widget_data =
GetTraceRestrictValue ( item ) ? STR_TRACE_RESTRICT_PF_ALLOW : STR_TRACE_RESTRICT_PF_DENY ;
break ;
case TRVT_ORDER :
right_sel - > SetDisplayedPlane ( DPR_VALUE_DEST ) ;
this - > EnableWidget ( TR_WIDGET_VALUE_DEST ) ;
break ;
case TRVT_CARGO_ID :
right_sel - > SetDisplayedPlane ( DPR_VALUE_DROPDOWN ) ;
this - > EnableWidget ( TR_WIDGET_VALUE_DROPDOWN ) ;
this - > GetWidget < NWidgetCore > ( TR_WIDGET_VALUE_DROPDOWN ) - > widget_data =
GetCargoStringByID ( GetTraceRestrictValue ( item ) ) ;
break ;
case TRVT_DIRECTION :
right_sel - > SetDisplayedPlane ( DPR_VALUE_DROPDOWN ) ;
this - > EnableWidget ( TR_WIDGET_VALUE_DROPDOWN ) ;
this - > GetWidget < NWidgetCore > ( TR_WIDGET_VALUE_DROPDOWN ) - > widget_data =
GetDropDownStringByValue ( & _direction_value , GetTraceRestrictValue ( item ) ) ;
break ;
case TRVT_TILE_INDEX :
right_sel - > SetDisplayedPlane ( DPR_VALUE_SIGNAL ) ;
this - > EnableWidget ( TR_WIDGET_VALUE_SIGNAL ) ;
break ;
case TRVT_PF_PENALTY :
right_sel - > SetDisplayedPlane ( DPR_VALUE_DROPDOWN ) ;
this - > EnableWidget ( TR_WIDGET_VALUE_DROPDOWN ) ;
if ( GetTraceRestrictAuxField ( item ) = = TRPPAF_VALUE ) {
this - > GetWidget < NWidgetCore > ( TR_WIDGET_VALUE_DROPDOWN ) - > widget_data = STR_BLACK_COMMA ;
} else {
this - > GetWidget < NWidgetCore > ( TR_WIDGET_VALUE_DROPDOWN ) - > widget_data =
GetDropDownStringByValue ( & _pf_penalty_dropdown , GetPathfinderPenaltyDropdownIndex ( item ) ) ;
}
break ;
case TRVT_RESERVE_THROUGH :
right_sel - > SetDisplayedPlane ( DPR_VALUE_DROPDOWN ) ;
this - > EnableWidget ( TR_WIDGET_VALUE_DROPDOWN ) ;
this - > GetWidget < NWidgetCore > ( TR_WIDGET_VALUE_DROPDOWN ) - > widget_data =
GetTraceRestrictValue ( item ) ? STR_TRACE_RESTRICT_RESERVE_THROUGH_CANCEL : STR_TRACE_RESTRICT_RESERVE_THROUGH ;
break ;
case TRVT_LONG_RESERVE :
right_sel - > SetDisplayedPlane ( DPR_VALUE_DROPDOWN ) ;
this - > EnableWidget ( TR_WIDGET_VALUE_DROPDOWN ) ;
this - > GetWidget < NWidgetCore > ( TR_WIDGET_VALUE_DROPDOWN ) - > widget_data =
GetTraceRestrictValue ( item ) ? STR_TRACE_RESTRICT_LONG_RESERVE_CANCEL : STR_TRACE_RESTRICT_LONG_RESERVE ;
break ;
case TRVT_GROUP_INDEX :
right_sel - > SetDisplayedPlane ( DPR_VALUE_DROPDOWN ) ;
this - > EnableWidget ( TR_WIDGET_VALUE_DROPDOWN ) ;
switch ( GetTraceRestrictValue ( item ) ) {
case INVALID_GROUP :
this - > GetWidget < NWidgetCore > ( TR_WIDGET_VALUE_DROPDOWN ) - > widget_data = STR_TRACE_RESTRICT_VARIABLE_UNDEFINED ;
break ;
case DEFAULT_GROUP :
this - > GetWidget < NWidgetCore > ( TR_WIDGET_VALUE_DROPDOWN ) - > widget_data = STR_GROUP_DEFAULT_TRAINS ;
break ;
default :
this - > GetWidget < NWidgetCore > ( TR_WIDGET_VALUE_DROPDOWN ) - > widget_data = STR_GROUP_NAME ;
break ;
}
break ;
case TRVT_OWNER :
right_sel - > SetDisplayedPlane ( DPR_VALUE_DROPDOWN ) ;
this - > EnableWidget ( TR_WIDGET_VALUE_DROPDOWN ) ;
this - > GetWidget < NWidgetCore > ( TR_WIDGET_VALUE_DROPDOWN ) - > widget_data = STR_TRACE_RESTRICT_COMPANY ;
break ;
default :
break ;
}
}
this - > EnableWidget ( TR_WIDGET_INSERT ) ;
this - > EnableWidget ( TR_WIDGET_REMOVE ) ;
}
}
this - > SetDirty ( ) ;
}
/**
* Show a drop down list using @ p list_set , setting the pre - selected item to the one corresponding to @ p value
* This asserts if @ p value is not in @ p list_set , and @ p missing_ok is false
*/
void ShowDropDownListWithValue ( const TraceRestrictDropDownListSet * list_set , uint value , bool missing_ok ,
int button , uint32 disabled_mask , uint32 hidden_mask , uint width )
{
this - > drop_down_list_mapping [ button ] = list_set ;
int selected = GetDropDownListIndexByValue ( list_set , value , missing_ok ) ;
if ( button = = TR_WIDGET_VALUE_DROPDOWN ) this - > value_drop_down_is_company = false ;
ShowDropDownMenu ( this , list_set - > string_array , selected , button , disabled_mask , hidden_mask , width ) ;
}
/**
* Show a drop down list using @ p list_set , setting the pre - selected item to the one corresponding to @ p value
* This asserts if @ p value is not in @ p list_set , and @ p missing_ok is false
*/
void ShowCompanyDropDownListWithValue ( CompanyID value , bool missing_ok , int button )
{
DropDownList * list = new DropDownList ( ) ;
Company * c ;
FOR_ALL_COMPANIES ( c ) {
* ( list - > Append ( ) ) = MakeCompanyDropDownListItem ( c - > index ) ;
if ( c - > index = = value ) missing_ok = true ;
}
* ( list - > Append ( ) ) = new DropDownListStringItem ( STR_TRACE_RESTRICT_UNDEFINED_COMPANY , INVALID_COMPANY , false ) ;
if ( INVALID_COMPANY = = value ) missing_ok = true ;
assert ( missing_ok = = true ) ;
assert ( button = = TR_WIDGET_VALUE_DROPDOWN ) ;
this - > value_drop_down_is_company = true ;
ShowDropDownList ( this , list , value , button , 0 , true , false ) ;
}
/**
* Helper function to set or unset a SetObjectToPlaceWnd , for the given widget and cursor type
*/
void SetObjectToPlaceAction ( int widget , CursorID cursor )
{
if ( this - > current_placement_widget ! = - 1 & & widget ! = this - > current_placement_widget ) {
ResetObjectToPlace ( ) ;
}
this - > ToggleWidgetLoweredState ( widget ) ;
this - > SetWidgetDirty ( widget ) ;
if ( this - > IsWidgetLowered ( widget ) ) {
SetObjectToPlaceWnd ( cursor , PAL_NONE , HT_RECT , this ) ;
this - > current_placement_widget = widget ;
} else {
ResetObjectToPlace ( ) ;
this - > current_placement_widget = - 1 ;
}
}
/**
* This used for testing whether else or else - if blocks could be inserted , or replace the selection
* If @ p replace is true , replace selection with @ p item , else insert @ p item before selection
* Returns true if resulting instruction list passes validation
*/
bool GenericElseInsertionDryRun ( TraceRestrictItem item , bool replace )
{
if ( this - > selected_instruction < 1 ) return false ;
uint offset = this - > selected_instruction - 1 ;
const TraceRestrictProgram * prog = this - > GetProgram ( ) ;
if ( ! prog ) return false ;
std : : vector < TraceRestrictItem > items = prog - > items ; // copy
if ( offset > = ( TraceRestrictProgram : : GetInstructionCount ( items ) + ( replace ? 0 : 1 ) ) ) return false ; // off the end of the program
uint array_offset = TraceRestrictProgram : : InstructionOffsetToArrayOffset ( items , offset ) ;
if ( replace ) {
items [ array_offset ] = item ;
} else {
items . insert ( items . begin ( ) + array_offset , item ) ;
}
TraceRestrictProgramActionsUsedFlags actions_used_flags ;
return TraceRestrictProgram : : Validate ( items , actions_used_flags ) . Succeeded ( ) ;
}
/**
* Run GenericElseInsertionDryRun with an else instruction
*/
bool ElseInsertionDryRun ( bool replace )
{
TraceRestrictItem item = 0 ;
SetTraceRestrictType ( item , TRIT_COND_ENDIF ) ;
SetTraceRestrictCondFlags ( item , TRCF_ELSE ) ;
return GenericElseInsertionDryRun ( item , replace ) ;
}
/**
* Run GenericElseInsertionDryRun with an elif instruction
*/
bool ElseIfInsertionDryRun ( bool replace )
{
TraceRestrictItem item = 0 ;
SetTraceRestrictType ( item , TRIT_COND_UNDEFINED ) ;
SetTraceRestrictCondFlags ( item , TRCF_ELSE ) ;
return GenericElseInsertionDryRun ( item , replace ) ;
}
} ;
static const NWidgetPart _nested_program_widgets [ ] = {
// Title bar
NWidget ( NWID_HORIZONTAL ) ,
NWidget ( WWT_CLOSEBOX , COLOUR_GREY ) ,
NWidget ( WWT_CAPTION , COLOUR_GREY , TR_WIDGET_CAPTION ) , SetDataTip ( STR_TRACE_RESTRICT_CAPTION , STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS ) ,
NWidget ( WWT_SHADEBOX , COLOUR_GREY ) ,
NWidget ( WWT_STICKYBOX , COLOUR_GREY ) ,
EndContainer ( ) ,
// Program display
NWidget ( NWID_HORIZONTAL ) ,
NWidget ( WWT_PANEL , COLOUR_GREY , TR_WIDGET_INSTRUCTION_LIST ) , SetMinimalSize ( 372 , 62 ) , SetDataTip ( 0x0 , STR_TRACE_RESTRICT_INSTRUCTION_LIST_TOOLTIP ) , SetResize ( 1 , 1 ) , EndContainer ( ) ,
NWidget ( NWID_VSCROLLBAR , COLOUR_GREY , TR_WIDGET_SCROLLBAR ) ,
EndContainer ( ) ,
// Button Bar
NWidget ( NWID_HORIZONTAL ) ,
NWidget ( NWID_HORIZONTAL , NC_EQUALSIZE ) ,
NWidget ( NWID_SELECTION , INVALID_COLOUR , TR_WIDGET_SEL_TOP_LEFT_2 ) ,
NWidget ( WWT_DROPDOWN , COLOUR_GREY , TR_WIDGET_TYPE_NONCOND ) , SetMinimalSize ( 124 , 12 ) , SetFill ( 1 , 0 ) ,
SetDataTip ( STR_NULL , STR_TRACE_RESTRICT_TYPE_TOOLTIP ) , SetResize ( 1 , 0 ) ,
NWidget ( WWT_DROPDOWN , COLOUR_GREY , TR_WIDGET_CONDFLAGS ) , SetMinimalSize ( 124 , 12 ) , SetFill ( 1 , 0 ) ,
SetDataTip ( STR_NULL , STR_TRACE_RESTRICT_CONDFLAGS_TOOLTIP ) , SetResize ( 1 , 0 ) ,
NWidget ( WWT_TEXTBTN , COLOUR_GREY , TR_WIDGET_BLANK_L2 ) , SetMinimalSize ( 124 , 12 ) , SetFill ( 1 , 0 ) ,
SetDataTip ( STR_EMPTY , STR_NULL ) , SetResize ( 1 , 0 ) ,
EndContainer ( ) ,
NWidget ( NWID_SELECTION , INVALID_COLOUR , TR_WIDGET_SEL_TOP_LEFT ) ,
NWidget ( WWT_DROPDOWN , COLOUR_GREY , TR_WIDGET_TYPE_COND ) , SetMinimalSize ( 124 , 12 ) , SetFill ( 1 , 0 ) ,
SetDataTip ( STR_NULL , STR_TRACE_RESTRICT_TYPE_TOOLTIP ) , SetResize ( 1 , 0 ) ,
NWidget ( WWT_TEXTBTN , COLOUR_GREY , TR_WIDGET_BLANK_L ) , SetMinimalSize ( 124 , 12 ) , SetFill ( 1 , 0 ) ,
SetDataTip ( STR_EMPTY , STR_NULL ) , SetResize ( 1 , 0 ) ,
EndContainer ( ) ,
NWidget ( NWID_SELECTION , INVALID_COLOUR , TR_WIDGET_SEL_TOP_MIDDLE ) ,
NWidget ( WWT_DROPDOWN , COLOUR_GREY , TR_WIDGET_COMPARATOR ) , SetMinimalSize ( 124 , 12 ) , SetFill ( 1 , 0 ) ,
SetDataTip ( STR_NULL , STR_TRACE_RESTRICT_COND_COMPARATOR_TOOLTIP ) , SetResize ( 1 , 0 ) ,
NWidget ( WWT_TEXTBTN , COLOUR_GREY , TR_WIDGET_BLANK_M ) , SetMinimalSize ( 124 , 12 ) , SetFill ( 1 , 0 ) ,
SetDataTip ( STR_EMPTY , STR_NULL ) , SetResize ( 1 , 0 ) ,
EndContainer ( ) ,
NWidget ( NWID_SELECTION , INVALID_COLOUR , TR_WIDGET_SEL_TOP_RIGHT ) ,
NWidget ( WWT_TEXTBTN , COLOUR_GREY , TR_WIDGET_VALUE_INT ) , SetMinimalSize ( 124 , 12 ) , SetFill ( 1 , 0 ) ,
SetDataTip ( STR_BLACK_COMMA , STR_TRACE_RESTRICT_COND_VALUE_TOOLTIP ) , SetResize ( 1 , 0 ) ,
NWidget ( WWT_DROPDOWN , COLOUR_GREY , TR_WIDGET_VALUE_DROPDOWN ) , SetMinimalSize ( 124 , 12 ) , SetFill ( 1 , 0 ) ,
SetDataTip ( STR_NULL , STR_TRACE_RESTRICT_COND_VALUE_TOOLTIP ) , SetResize ( 1 , 0 ) ,
NWidget ( WWT_TEXTBTN , COLOUR_GREY , TR_WIDGET_VALUE_DEST ) , SetMinimalSize ( 124 , 12 ) , SetFill ( 1 , 0 ) ,
SetDataTip ( STR_TRACE_RESTRICT_SELECT_TARGET , STR_TRACE_RESTRICT_SELECT_TARGET ) , SetResize ( 1 , 0 ) ,
NWidget ( WWT_TEXTBTN , COLOUR_GREY , TR_WIDGET_VALUE_SIGNAL ) , SetMinimalSize ( 124 , 12 ) , SetFill ( 1 , 0 ) ,
SetDataTip ( STR_TRACE_RESTRICT_SELECT_SIGNAL , STR_TRACE_RESTRICT_SELECT_SIGNAL ) , SetResize ( 1 , 0 ) ,
NWidget ( WWT_TEXTBTN , COLOUR_GREY , TR_WIDGET_BLANK_R ) , SetMinimalSize ( 124 , 12 ) , SetFill ( 1 , 0 ) ,
SetDataTip ( STR_EMPTY , STR_NULL ) , SetResize ( 1 , 0 ) ,
EndContainer ( ) ,
EndContainer ( ) ,
NWidget ( WWT_IMGBTN , COLOUR_GREY , TR_WIDGET_GOTO_SIGNAL ) , SetMinimalSize ( 12 , 12 ) , SetDataTip ( SPR_ARROW_RIGHT , STR_TRACE_RESTRICT_GOTO_SIGNAL_TOOLTIP ) ,
EndContainer ( ) ,
/* Second button row. */
NWidget ( NWID_HORIZONTAL ) ,
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 ( 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 ( ) ,
} ;
static WindowDesc _program_desc (
WDP_AUTO , " trace_restrict_gui " , 384 , 100 ,
WC_TRACE_RESTRICT , WC_BUILD_SIGNAL ,
WDF_CONSTRUCTION ,
_nested_program_widgets , lengthof ( _nested_program_widgets )
) ;
/**
* Show or create program window for given @ p tile and @ p track
*/
void ShowTraceRestrictProgramWindow ( TileIndex tile , Track track )
{
if ( BringWindowToFrontById ( WC_TRACE_RESTRICT , MakeTraceRestrictRefId ( tile , track ) ) ! = NULL ) {
return ;
}
new TraceRestrictWindow ( & _program_desc , tile , track ) ;
}