Index: src/rail_gui.cpp =================================================================== --- src/rail_gui.cpp (revision 17180) +++ src/rail_gui.cpp (working copy) @@ -314,7 +314,7 @@ /** Updates the Remove button because of Ctrl state change * @param w window the button belongs to - * @return true iff the remove buton was changed + * @return true if the remove button was changed */ static bool RailToolbar_CtrlChanged(Window *w) { @@ -1536,7 +1536,13 @@ virtual void OnPaint() { - this->LowerWidget((_cur_signal_variant == SIG_ELECTRIC ? BSW_ELECTRIC_NORM : BSW_SEMAPHORE_NORM) + _cur_signal_type); + /* Only lower the currently selected widget if none has been lowered yet. + * This way widgets can be modified without changing _cur_signal_variant + */ + if (!this->IsWidgetLowered(BSW_ELECTRIC_NORM + _cur_signal_type) && !this->IsWidgetLowered(BSW_SEMAPHORE_NORM + _cur_signal_type)) { + this->LowerWidget(((_cur_signal_variant == SIG_ELECTRIC) ? BSW_ELECTRIC_NORM : BSW_SEMAPHORE_NORM) + _cur_signal_type); + if (_ctrl_pressed) OnCTRLStateChange(); // when a button is ctrl-clicked + } this->SetWidgetLoweredState(BSW_CONVERT, _convert_signal_button); @@ -1581,7 +1587,7 @@ case BSW_ELECTRIC_COMBO: case BSW_ELECTRIC_PBS: case BSW_ELECTRIC_PBS_OWAY: - this->RaiseWidget((_cur_signal_variant == SIG_ELECTRIC ? BSW_ELECTRIC_NORM : BSW_SEMAPHORE_NORM) + _cur_signal_type); + this->RaiseWidget((this->IsWidgetLowered(BSW_ELECTRIC_NORM + _cur_signal_type) ? BSW_ELECTRIC_NORM : BSW_SEMAPHORE_NORM) + _cur_signal_type); _cur_signal_type = (SignalType)((uint)((widget - BSW_SEMAPHORE_NORM) % (SIGTYPE_LAST + 1))); _cur_signal_variant = widget >= BSW_ELECTRIC_NORM ? SIG_ELECTRIC : SIG_SEMAPHORE; @@ -1589,6 +1595,10 @@ case BSW_CONVERT: _convert_signal_button = !_convert_signal_button; + if (_convert_signal_button && _ctrl_pressed) { + this->RaiseWidget((this->IsWidgetLowered(BSW_ELECTRIC_NORM + _cur_signal_type) + ? BSW_ELECTRIC_NORM : BSW_SEMAPHORE_NORM) + _cur_signal_type); + } break; case BSW_DRAG_SIGNALS_DENSITY_DECREASE: @@ -1610,6 +1620,22 @@ this->SetDirty(); } + + virtual EventState OnCTRLStateChange() + { + /* One of the button states needs to be stored, otherwise both button variants end up in the same state. */ + bool electric_lowered = this->IsWidgetLowered(BSW_ELECTRIC_NORM + _cur_signal_type); + /* Using the signal converter with ctrl doesn't depend on selected signal, + * so it's clearer to raise the selected signal button for the duration of ctrl-press. */ + if (_convert_signal_button && _ctrl_pressed) { + this->RaiseWidget((electric_lowered ? BSW_ELECTRIC_NORM : BSW_SEMAPHORE_NORM) + _cur_signal_type); + } else { + this->SetWidgetLoweredState(BSW_ELECTRIC_NORM + _cur_signal_type, (this->IsWidgetLowered(BSW_SEMAPHORE_NORM + _cur_signal_type)) ? 1 : 0); + this->SetWidgetLoweredState(BSW_SEMAPHORE_NORM + _cur_signal_type, electric_lowered ? 1 : 0); + } + this->SetDirty(); + return ES_NOT_HANDLED; + } }; /** Nested widget definition of the build signal window */