Skip to content
Open
4 changes: 4 additions & 0 deletions resource/UKControllerPlugin.rc
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ BEGIN
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,25,118,10
CONTROL "Notify Departure Release Activity In Chat Area",IDC_RELEASE_CHAT_MESSAGE,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,34,152,10
COMBOBOX IDC_COLOUR_PALETTE,178,16,48,56,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "Colour Palette",IDC_STATIC,230,18,43,8
END

IDD_TIMER_CONFIGURATION DIALOGEX 0, 0, 179, 158
Expand Down Expand Up @@ -391,6 +393,8 @@ BEGIN
RIGHTMARGIN, 302
TOPMARGIN, 7
BOTTOMMARGIN, 169
HORZGUIDE, 16
HORZGUIDE, 22
END

IDD_TIMER_CONFIGURATION, DIALOG
Expand Down
3 changes: 2 additions & 1 deletion resource/resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,14 +207,15 @@
#define IDC_API_KEY_STATIC 1144
#define IDC_ 1145
#define IDC_RELEASE_CHAT_MESSAGE 1145
#define IDC_COLOUR_PALETTE 1146

// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 147
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1146
#define _APS_NEXT_CONTROL_VALUE 1147
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
4 changes: 4 additions & 0 deletions src/plugin/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,10 @@ set(src__geometry
source_group("src\\geometry" FILES ${src__geometry})

set(src__graphics
"graphics/ColourPaletteDefinitions.cpp"
"graphics/ColourPaletteDefinitions.h"
"graphics/ThemingModule.cpp"
"graphics/ThemingModule.h"
"graphics/GdiGraphicsInterface.h"
"graphics/GdiGraphicsWrapper.cpp"
"graphics/GdiGraphicsWrapper.h"
Expand Down
4 changes: 4 additions & 0 deletions src/plugin/approach/ApproachBootstrapProvider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
#include "radarscreen/RadarRenderableCollection.h"
#include "tag/TagItemCollection.h"
#include "timedevent/TimedEventCollection.h"
#include "graphics/GdiplusBrushes.h"

using UKControllerPlugin::Windows::GdiplusBrushes;

namespace UKControllerPlugin::Approach {

Expand Down Expand Up @@ -92,6 +95,7 @@ namespace UKControllerPlugin::Approach {
container.moduleFactories->Approach().SequencerOptions(), displayOptions),
"Toggle sequencer airfield separation selector"),
*container.plugin,
*container.brushes,
sequencerScreenObjectId),
RadarScreen::RadarRenderableCollection::beforeTags);

Expand Down
6 changes: 6 additions & 0 deletions src/plugin/approach/ApproachBootstrapProvider.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
#pragma once
#include "bootstrap/BootstrapProviderInterface.h"

namespace UKControllerPlugin {
namespace Windows {
struct GdiplusBrushes;
} // namespace Windows
}

namespace UKControllerPlugin::Approach {
class ApproachBootstrapProvider : public Bootstrap::BootstrapProviderInterface
{
Expand Down
69 changes: 35 additions & 34 deletions src/plugin/approach/ApproachSequencerDisplay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@
#include "helper/HelperFunctions.h"
#include "list/PopupListInterface.h"
#include "number/NumberFormat.h"
#include "graphics/GdiplusBrushes.h"

using UKControllerPlugin::Components::CollapsibleWindowTitleBar;
using UKControllerPlugin::Number::To1Dp;
using UKControllerPlugin::Number::To1DpWide;
using UKControllerPlugin::Windows::GdiplusBrushes;

namespace UKControllerPlugin::Approach {

Expand All @@ -35,28 +37,27 @@ namespace UKControllerPlugin::Approach {
std::shared_ptr<List::PopupListInterface> airfieldTargetSelector,
std::shared_ptr<List::PopupListInterface> airfieldSeparationSelector,
Euroscope::EuroscopePluginLoopbackInterface& plugin,
const GdiplusBrushes& brushes,
int screenObjectId)
: sequencer(sequencer), spacingCalculator(spacingCalculator), options(options),
displayOptions(std::move(displayOptions)), airfieldSelector(std::move(airfieldSelector)),
callsignSelector(std::move(callsignSelector)), targetSelector(std::move(targetSelector)),
airfieldTargetSelector(std::move(airfieldTargetSelector)),
airfieldSeparationSelector(std::move(airfieldSeparationSelector)), plugin(plugin),
screenObjectId(screenObjectId), titleBar(CollapsibleWindowTitleBar::Create(
brushes(brushes), screenObjectId(screenObjectId), titleBar(CollapsibleWindowTitleBar::Create(
L"Approach Sequencer",
titleBarArea,
[this]() -> bool { return this->displayOptions->ContentCollapsed(); },
screenObjectId)),
screenObjectId,
brushes)),
airfieldClickspot(Components::ClickableArea::Create(
this->airfieldTextArea, screenObjectId, AIRFIELD_SELECTOR_CLICKSPOT, false)),
addClickspot(
Components::ClickableArea::Create(this->addButton, screenObjectId, ADD_AIRCRAFT_CLICKSPOT, false)),
airfieldTargetClickspot(Components::ClickableArea::Create(
this->airfieldTargetTextArea, screenObjectId, AIRFIELD_TARGET_CLICKSPOT, false)),
airfieldSeparationClickspot(Components::ClickableArea::Create(
this->airfieldSeparationTextArea, screenObjectId, AIRFIELD_SEPARATION_CLICKSPOT, false)),
backgroundBrush(std::make_shared<Gdiplus::SolidBrush>(BACKGROUND_COLOUR)),
textBrush(std::make_shared<Gdiplus::SolidBrush>(TEXT_COLOUR)),
dividingPen(std::make_shared<Gdiplus::Pen>(TEXT_COLOUR))
this->airfieldSeparationTextArea, screenObjectId, AIRFIELD_SEPARATION_CLICKSPOT, false))
{
}

Expand All @@ -76,12 +77,12 @@ namespace UKControllerPlugin::Approach {
graphics.Translated(
displayOptions->Position().x, displayOptions->Position().y, [this, &graphics, &radarScreen]() {
if (this->displayOptions->ContentCollapsed()) {
this->titleBar->Draw(graphics, radarScreen);
this->titleBar->DrawTheme(graphics, radarScreen, brushes);
return;
}

this->RenderBackground(graphics);
this->titleBar->Draw(graphics, radarScreen);
this->titleBar->DrawTheme(graphics, radarScreen, brushes);
this->RenderAirfield(graphics, radarScreen);
this->RenderAddButton(graphics, radarScreen);
this->RenderAirfieldTarget(graphics, radarScreen);
Expand Down Expand Up @@ -173,39 +174,39 @@ namespace UKControllerPlugin::Approach {
graphics.DrawString(
L"Airfield:",
airfieldStaticArea,
*textBrush,
Gdiplus::SolidBrush(this->brushes.text),
Graphics::StringFormatManager::Instance().GetLeftAlign(),
Graphics::FontManager::Instance().GetDefault());

graphics.DrawString(
HelperFunctions::ConvertToWideString(
displayOptions->Airfield().empty() ? "--" : displayOptions->Airfield()),
airfieldTextArea,
*textBrush,
Gdiplus::SolidBrush(this->brushes.text),
Graphics::StringFormatManager::Instance().GetLeftAlign(),
Graphics::FontManager::Instance().GetDefault());
this->airfieldClickspot->Apply(graphics, radarScreen);
}

void ApproachSequencerDisplay::RenderDivider(Windows::GdiGraphicsInterface& graphics)
{
graphics.DrawLine(*dividingPen, dividerLeft, dividerRight);
graphics.DrawLine(Gdiplus::Pen(this->brushes.text), dividerLeft, dividerRight);
}

void ApproachSequencerDisplay::RenderHeaders(Windows::GdiGraphicsInterface& graphics)
{
graphics.DrawString(L"#", numberHeader, *textBrush);
graphics.DrawString(L"Callsign", callsignHeader, *textBrush);
graphics.DrawString(L"Target", targetHeader, *textBrush);
graphics.DrawString(L"Actual", actualHeader, *textBrush);
graphics.DrawString(L"Actions", actionsHeader, *textBrush);
graphics.DrawString(L"#", numberHeader, Gdiplus::SolidBrush(this->brushes.text));
graphics.DrawString(L"Callsign", callsignHeader, Gdiplus::SolidBrush(this->brushes.text));
graphics.DrawString(L"Target", targetHeader, Gdiplus::SolidBrush(this->brushes.text));
graphics.DrawString(L"Actual", actualHeader, Gdiplus::SolidBrush(this->brushes.text));
graphics.DrawString(L"Actions", actionsHeader, Gdiplus::SolidBrush(this->brushes.text));
}

void ApproachSequencerDisplay::RenderAddButton(
Windows::GdiGraphicsInterface& graphics, Euroscope::EuroscopeRadarLoopbackInterface& radarScreen)
{
graphics.DrawRect(addButton, *dividingPen);
graphics.DrawString(L"Add Aircraft", addButton, *textBrush);
graphics.DrawRect(addButton, Gdiplus::Pen(this->brushes.text));
graphics.DrawString(L"Add Aircraft", addButton, Gdiplus::SolidBrush(this->brushes.text));
addClickspot->Apply(graphics, radarScreen);
}

Expand Down Expand Up @@ -248,46 +249,46 @@ namespace UKControllerPlugin::Approach {
int sequenceNumber = 1;

while (aircraftToProcess != nullptr) {
graphics.DrawString(std::to_wstring(sequenceNumber), numberRect, *textBrush);
graphics.DrawString(std::to_wstring(sequenceNumber), numberRect, Gdiplus::SolidBrush(this->brushes.text));
graphics.DrawString(
HelperFunctions::ConvertToWideString(aircraftToProcess->Callsign()), callsignRect, *textBrush);
HelperFunctions::ConvertToWideString(aircraftToProcess->Callsign()), callsignRect, Gdiplus::SolidBrush(this->brushes.text));

// The target distance / wake
if (aircraftToProcess->Mode() == ApproachSequencingMode::WakeTurbulence) {
graphics.DrawString(L"Wake", targetRect, *textBrush);
graphics.DrawString(L"Wake", targetRect, Gdiplus::SolidBrush(this->brushes.text));
} else {
graphics.DrawString(To1DpWide(aircraftToProcess->ExpectedDistance()), targetRect, *textBrush);
graphics.DrawString(To1DpWide(aircraftToProcess->ExpectedDistance()), targetRect, Gdiplus::SolidBrush(this->brushes.text));
}
Components::ClickableArea::Create(
targetRect, screenObjectId, "approachTarget" + aircraftToProcess->Callsign(), false)
->Apply(graphics, radarScreen);

double requiredSpacing = spacingCalculator.Calculate(displayOptions->Airfield(), *aircraftToProcess);
if (requiredSpacing == spacingCalculator.NoSpacing()) {
graphics.DrawString(L"--", actualRect, *textBrush);
graphics.DrawString(L"--", actualRect, Gdiplus::SolidBrush(this->brushes.text));
} else {
graphics.DrawString(To1DpWide(requiredSpacing), actualRect, *textBrush);
graphics.DrawString(To1DpWide(requiredSpacing), actualRect, Gdiplus::SolidBrush(this->brushes.text));
}

auto upButton = Components::Button::Create(
upButtonRect,
screenObjectId,
"moveUp" + aircraftToProcess->Callsign(),
Components::UpArrow(TEXT_COLOUR));
Components::UpArrow(this->brushes.text));
upButton->Draw(graphics, radarScreen);

auto downButton = Components::Button::Create(
downButtonRect,
screenObjectId,
"moveDown" + aircraftToProcess->Callsign(),
Components::DownArrow(TEXT_COLOUR));
Components::DownArrow(this->brushes.text));
downButton->Draw(graphics, radarScreen);

auto deleteButton = Components::Button::Create(
deleteButtonRect,
screenObjectId,
"deleteButton" + aircraftToProcess->Callsign(),
Components::DeleteButton(TEXT_COLOUR));
Components::DeleteButton(this->brushes.text));
deleteButton->Draw(graphics, radarScreen);

auto toggleButton = Components::Button::Create(
Expand All @@ -297,13 +298,13 @@ namespace UKControllerPlugin::Approach {
[&aircraftToProcess, &radarScreen, this](
Windows::GdiGraphicsInterface& graphics, const Gdiplus::Rect& area) {
Gdiplus::Rect drawArea = {0, 0, area.Width, area.Height};
graphics.FillCircle(drawArea, *textBrush);
graphics.FillCircle(drawArea, Gdiplus::SolidBrush(this->brushes.text));
if (!aircraftToProcess->ShouldDraw()) {
Components::Button::Create(
drawArea,
screenObjectId,
"toggleDraw" + aircraftToProcess->Callsign(),
Components::DeleteButton(BACKGROUND_COLOUR))
Components::DeleteButton(this->brushes.background))
->Draw(graphics, radarScreen);
}
});
Expand Down Expand Up @@ -332,7 +333,7 @@ namespace UKControllerPlugin::Approach {
TITLE_BAR_HEIGHT,
WINDOW_WIDTH,
static_cast<INT>(callsignHeader.GetBottom() + INSETS + (numberOfCallsigns * callsignHeader.Height))};
graphics.FillRect(contentArea, *backgroundBrush);
graphics.FillRect(contentArea, Gdiplus::SolidBrush(this->brushes.background));
}

void ApproachSequencerDisplay::RenderAirfieldTarget(
Expand All @@ -341,7 +342,7 @@ namespace UKControllerPlugin::Approach {
graphics.DrawString(
L"Target:",
airfieldTargetStatic,
*textBrush,
Gdiplus::SolidBrush(this->brushes.text),
Graphics::StringFormatManager::Instance().GetLeftAlign(),
Graphics::FontManager::Instance().GetDefault());

Expand All @@ -356,7 +357,7 @@ namespace UKControllerPlugin::Approach {
graphics.DrawString(
targetString,
airfieldTargetTextArea,
*textBrush,
Gdiplus::SolidBrush(this->brushes.text),
Graphics::StringFormatManager::Instance().GetLeftAlign(),
Graphics::FontManager::Instance().GetDefault());
this->airfieldTargetClickspot->Apply(graphics, radarScreen);
Expand All @@ -368,7 +369,7 @@ namespace UKControllerPlugin::Approach {
graphics.DrawString(
L"Separation:",
airfieldSeparationStatic,
*textBrush,
Gdiplus::SolidBrush(this->brushes.text),
Graphics::StringFormatManager::Instance().GetLeftAlign(),
Graphics::FontManager::Instance().GetDefault());

Expand All @@ -377,7 +378,7 @@ namespace UKControllerPlugin::Approach {
? L"--"
: To1DpWide(options.Get(displayOptions->Airfield()).minimumSeparationRequirement),
airfieldSeparationTextArea,
*textBrush,
Gdiplus::SolidBrush(this->brushes.text),
Graphics::StringFormatManager::Instance().GetLeftAlign(),
Graphics::FontManager::Instance().GetDefault());
this->airfieldSeparationClickspot->Apply(graphics, radarScreen);
Expand Down
14 changes: 8 additions & 6 deletions src/plugin/approach/ApproachSequencerDisplay.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ namespace UKControllerPlugin {
namespace List {
class PopupListInterface;
} // namespace List
namespace Windows {
struct GdiplusBrushes;
} // namespace Windows
} // namespace UKControllerPlugin

namespace UKControllerPlugin::Approach {
Expand All @@ -37,6 +40,7 @@ namespace UKControllerPlugin::Approach {
std::shared_ptr<List::PopupListInterface> airfieldTargetSelector,
std::shared_ptr<List::PopupListInterface> airfieldSeparationSelector,
Euroscope::EuroscopePluginLoopbackInterface& plugin,
const UKControllerPlugin::Windows::GdiplusBrushes& brushes,
int screenObjectId);
[[nodiscard]] auto IsVisible() const -> bool override;
void LeftClick(
Expand Down Expand Up @@ -67,7 +71,7 @@ namespace UKControllerPlugin::Approach {

// Dimensions
inline static const int WINDOW_WIDTH = 435;
inline static const int TITLE_BAR_HEIGHT = 20;
inline static const int TITLE_BAR_HEIGHT = 15;
inline static const int INSETS = 5;

// Clickspot
Expand Down Expand Up @@ -105,6 +109,9 @@ namespace UKControllerPlugin::Approach {

// The plugin
Euroscope::EuroscopePluginLoopbackInterface& plugin;

// Pens and brushes
const UKControllerPlugin::Windows::GdiplusBrushes& brushes;

// The screen object id
int screenObjectId;
Expand Down Expand Up @@ -138,10 +145,5 @@ namespace UKControllerPlugin::Approach {
std::shared_ptr<Components::ClickableArea> airfieldTargetClickspot;
std::shared_ptr<Components::ClickableArea> airfieldSeparationClickspot;

const Gdiplus::Color BACKGROUND_COLOUR = Gdiplus::Color(64, 64, 64);
const Gdiplus::Color TEXT_COLOUR = Gdiplus::Color(225, 225, 225);
std::shared_ptr<Gdiplus::Brush> backgroundBrush;
std::shared_ptr<Gdiplus::Brush> textBrush;
std::shared_ptr<Gdiplus::Pen> dividingPen;
};
} // namespace UKControllerPlugin::Approach
7 changes: 6 additions & 1 deletion src/plugin/bootstrap/InitialisePlugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
#include "task/TaskRunnerInterface.h"
#include "update/PluginVersion.h"
#include "wake/WakeModule.h"
#include "graphics/ThemingModule.h"

using UKControllerPlugin::Bootstrap::CollectionBootstrap;
using UKControllerPlugin::Bootstrap::EventHandlerCollectionBootstrap;
Expand Down Expand Up @@ -92,6 +93,7 @@ using UKControllerPlugin::Plugin::PluginVersion;
using UKControllerPlugin::Prenote::PrenoteModule;
using UKControllerPlugin::Regional::RegionalPressureModule;
using UKControllerPlugin::Squawk::SquawkModule;
using UKControllerPlugin::Graphics::ThemingModule;

namespace UKControllerPlugin {
/*
Expand Down Expand Up @@ -236,13 +238,16 @@ namespace UKControllerPlugin {
LoginModule::BootstrapPlugin(*this->container);
SectorFile::BootstrapPlugin(*this->container);

ThemingModule::BootstrapPlugin(*this->container, *this->container->pluginUserSettingHandler);

// General settings config bootstrap
GeneralSettingsConfigurationBootstrap::BootstrapPlugin(
*this->container->dialogManager,
*this->container->pluginUserSettingHandler,
*this->container->userSettingHandlers,
*this->container->settingsRepository,
*this->container->windows);
*this->container->windows,
*this->container->brushes);

// Bootstrap the modules
Metar::BootstrapPlugin(*this->container);
Expand Down
Loading