Skip to content

Commit b4013b7

Browse files
authored
Merge pull request #15 from EvenAR/custom-labels
Custom labels + closeable window
2 parents 118f290 + d7c81a7 commit b4013b7

21 files changed

+416
-223
lines changed

Aman/Aman.vcxproj

+1
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@
210210
</ItemGroup>
211211
<ItemGroup>
212212
<ClInclude Include="..\..\..\..\..\..\..\Program Files (x86)\EuroScope\PlugInEnvironment\EuroScopePlugIn.h" />
213+
<ClInclude Include="AmanTagItem.h" />
213214
<ClInclude Include="EventEmitter.h" />
214215
<ClInclude Include="Aman.h" />
215216
<ClInclude Include="AmanAircraft.h" />

Aman/Aman.vcxproj.filters

+3
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,9 @@
115115
<ClInclude Include="MenuBar.h">
116116
<Filter>Header Files</Filter>
117117
</ClInclude>
118+
<ClInclude Include="AmanTagItem.h">
119+
<Filter>Header Files</Filter>
120+
</ClInclude>
118121
</ItemGroup>
119122
<ItemGroup>
120123
<ResourceCompile Include="Aman.rc">

Aman/AmanAircraft.h

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ class AmanAircraft {
99
std::string arrivalRunway;
1010
std::string icaoType;
1111
std::string nextFix;
12+
std::string scratchPad;
1213

1314
int viaFixIndex;
1415

Aman/AmanController.cpp

+19-7
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66

77
AmanController::AmanController(AmanPlugIn* plugin) {
88
this->amanModel = plugin;
9-
this->amanWindow = NULL;
10-
this->amanWindow = std::make_shared<AmanWindow>(this);
119
}
1210

1311
AmanController::~AmanController() {}
@@ -22,9 +20,7 @@ void AmanController::modelUpdated() {
2220
}
2321

2422
void AmanController::toggleTimeline(const std::string& id) {
25-
bool isActive = std::find(activeTimelines.begin(), activeTimelines.end(), id) != activeTimelines.end();
26-
27-
if (isActive) {
23+
if (isTimelineActive(id)) {
2824
activeTimelines.erase(
2925
std::remove(activeTimelines.begin(), activeTimelines.end(), id),
3026
activeTimelines.end()
@@ -35,11 +31,27 @@ void AmanController::toggleTimeline(const std::string& id) {
3531
modelUpdated();
3632
}
3733

34+
bool AmanController::isTimelineActive(const std::string& id) {
35+
return std::find(activeTimelines.begin(), activeTimelines.end(), id) != activeTimelines.end();
36+
}
37+
3838
void AmanController::reloadProfiles() {
3939
this->amanModel->requestReload();
4040
}
4141

42-
void AmanController::setTimelineHorizon(const std::string& id, uint32_t minutes) {
43-
this->amanWindow->setTimelineHorizon(id, minutes);
42+
bool AmanController::openWindow() {
43+
if (this->amanWindow == nullptr) {
44+
this->amanWindow = std::make_shared<AmanWindow>(this);
45+
return true;
46+
}
47+
}
48+
49+
bool AmanController::closeWindow() {
50+
if (this->amanWindow == nullptr) {
51+
return false;
52+
} else {
53+
this->amanWindow.reset();
54+
return true;
55+
}
4456
}
4557

Aman/AmanController.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ class AmanController {
1212
AmanController(AmanPlugIn* model);
1313
void modelUpdated();
1414
void toggleTimeline(const std::string& id);
15+
bool isTimelineActive(const std::string& id);
1516
void reloadProfiles();
16-
void setTimelineHorizon(const std::string& id, uint32_t minutes);
17+
bool openWindow();
18+
bool closeWindow();
1719

1820
~AmanController();
1921

Aman/AmanPlugIn.cpp

+78-36
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "AmanPlugIn.h"
66
#include "AmanTimeline.h"
77
#include "AmanWindow.h"
8+
#include "AmanTagItem.h"
89
#include "stdafx.h"
910
#include "windows.h"
1011
#include "rapidjson/document.h"
@@ -17,6 +18,7 @@
1718
#include <string>
1819
#include <vector>
1920
#include <fstream>
21+
#include <map>
2022

2123
#define TO_UPPERCASE(str) std::transform(str.begin(), str.end(), str.begin(), ::toupper);
2224
#define REMOVE_EMPTY(strVec, output) \
@@ -26,26 +28,24 @@
2628
str.pop_back();
2729
#define DISPLAY_WARNING(str) DisplayUserMessage("Aman", "Warning", str, true, true, true, true, false);
2830

29-
AmanPlugIn::AmanPlugIn() : CPlugIn(COMPATIBILITY_CODE, "Arrival Manager", "2.1.0", "https://git.io/Jt3S8", "Open source") {
31+
AmanPlugIn::AmanPlugIn() : CPlugIn(COMPATIBILITY_CODE, "Arrival Manager", "3.0.1", "https://git.io/Jt3S8", "Open source") {
3032
// Find directory of this .dll
3133
char fullPluginPath[_MAX_PATH];
3234
GetModuleFileNameA((HINSTANCE)&__ImageBase, fullPluginPath, sizeof(fullPluginPath));
3335
std::string fullPluginPathStr(fullPluginPath);
3436
pluginDirectory = fullPluginPathStr.substr(0, fullPluginPathStr.find_last_of("\\"));
35-
3637
amanController = std::make_shared<AmanController>(this);
37-
3838
loadTimelines("aman-config.json");
39-
4039
amanController->modelUpdated();
4140
}
4241

4342
AmanPlugIn::~AmanPlugIn() {
43+
4444
}
4545

4646
std::set<std::string> AmanPlugIn::getAvailableIds() {
4747
std::set<std::string> set;
48-
for (auto timeline : timelines) {
48+
for (auto& timeline : timelines) {
4949
set.insert(timeline->getIdentifier());
5050
}
5151
return set;
@@ -115,6 +115,7 @@ std::vector<AmanAircraft> AmanPlugIn::getInboundsForFix(const std::string& fixNa
115115
ac.eta = timeNow + timeToFix - rt.GetPosition().GetReceivedTime();
116116
ac.distLeft = findRemainingDist(rt, route, targetFixIndex);
117117
ac.secondsBehindPreceeding = 0; // Updated in the for-loop below
118+
ac.scratchPad = rt.GetCorrelatedFlightPlan().GetControllerAssignedData().GetScratchPadString();
118119
aircraftList.push_back(ac);
119120
}
120121
}
@@ -138,9 +139,19 @@ void AmanPlugIn::OnTimer(int Counter) {
138139
amanController->modelUpdated();
139140
}
140141

142+
bool AmanPlugIn::OnCompileCommand(const char* sCommandLine) {
143+
if (strcmp(sCommandLine, ".aman open") == 0) {
144+
return this->amanController->openWindow();
145+
} else if (strcmp(sCommandLine, ".aman close") == 0) {
146+
return this->amanController->closeWindow();
147+
}
148+
return false;
149+
}
150+
141151
void AmanPlugIn::loadTimelines(const std::string& filename) {
142152
std::ifstream file(pluginDirectory + "\\" + filename);
143153
std::string fileContent((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
154+
std::map<std::string, std::vector<std::shared_ptr<TagItem>>> tagLayouts;
144155

145156
if (fileContent.empty()) {
146157
DISPLAY_WARNING((filename + ": the JSON-file was not found or is empty").c_str());
@@ -159,44 +170,75 @@ void AmanPlugIn::loadTimelines(const std::string& filename) {
159170
return;
160171
}
161172

162-
for (auto& v : document["timelines"].GetArray()) {
163-
auto object = v.GetObjectA();
164-
165-
std::vector<std::string> targetFixes;
166-
for (auto& fix : object["targetFixes"].GetArray()) {
167-
targetFixes.push_back(fix.GetString());
173+
if (document.HasMember("tagLayouts") && document["tagLayouts"].IsObject()) {
174+
for (auto property = document["tagLayouts"].MemberBegin(); property != document["tagLayouts"].MemberEnd(); ++property) {
175+
auto layoutId = property->name.GetString();
176+
std::vector<std::shared_ptr<TagItem>> tagItems;
177+
for (auto& tagItemObj : property->value.GetArray()) {
178+
auto dataSource = tagItemObj.HasMember("source") ? tagItemObj["source"].GetString() : "";
179+
auto width = tagItemObj.HasMember("width") ? tagItemObj["width"].GetUint() : 1;
180+
auto defaultValue = tagItemObj.HasMember("defaultValue") ? tagItemObj["defaultValue"].GetString() : "";
181+
auto alignRight = tagItemObj.HasMember("rightAligned") && tagItemObj["rightAligned"].GetBool();
182+
auto isViaFixIndicator = tagItemObj.HasMember("isViaFixIndicator") && tagItemObj["isViaFixIndicator"].GetBool();
183+
184+
tagItems.push_back(std::make_shared<TagItem>(dataSource, defaultValue, width, alignRight, isViaFixIndicator));
185+
}
186+
tagLayouts[layoutId] = tagItems;
168187
}
188+
}
189+
190+
if (document.HasMember("timelines") && document["timelines"].IsObject()) {
191+
for (auto property = document["timelines"].MemberBegin(); property != document["timelines"].MemberEnd(); ++property) {
192+
auto object = property->value.GetObjectA();
169193

170-
std::vector<std::string> viaFixes;
171-
if (object.HasMember("viaFixes") && object["viaFixes"].IsArray()) {
172-
for (auto& fix : object["viaFixes"].GetArray()) {
173-
viaFixes.push_back(fix.GetString());
194+
std::vector<std::string> targetFixes;
195+
for (auto& fix : object["targetFixes"].GetArray()) {
196+
targetFixes.push_back(fix.GetString());
174197
}
175-
}
176198

177-
std::vector<std::string> destinationAirports;
178-
if (object.HasMember("destinationAirports") && object["destinationAirports"].IsArray()) {
179-
for (auto& destination : object["destinationAirports"].GetArray()) {
180-
destinationAirports.push_back(destination.GetString());
199+
std::vector<std::string> viaFixes;
200+
if (object.HasMember("viaFixes") && object["viaFixes"].IsArray()) {
201+
for (auto& fix : object["viaFixes"].GetArray()) {
202+
viaFixes.push_back(fix.GetString());
203+
}
181204
}
182-
}
183205

184-
std::string alias;
185-
if (object.HasMember("alias") && object["alias"].IsString()) {
186-
alias = object["alias"].GetString();
187-
} else {
188-
alias = "";
189-
for (const auto& piece : targetFixes) alias += piece + "/";
190-
alias = alias.substr(0, alias.size() - 1);
191-
}
206+
std::vector<std::string> destinationAirports;
207+
if (object.HasMember("destinationAirports") && object["destinationAirports"].IsArray()) {
208+
for (auto& destination : object["destinationAirports"].GetArray()) {
209+
destinationAirports.push_back(destination.GetString());
210+
}
211+
}
192212

193-
uint32_t startHorizon;
194-
if (object.HasMember("startHorizon") && object["startHorizon"].IsUint()) {
195-
startHorizon = object["startHorizon"].GetUint();
196-
amanController->setTimelineHorizon(alias, startHorizon);
213+
std::vector<std::shared_ptr<TagItem>> tagItems;
214+
if (object.HasMember("tagLayout") && object["tagLayout"].IsString()) {
215+
tagItems = tagLayouts[object["tagLayout"].GetString()];
216+
} else {
217+
tagItems = {};
218+
}
219+
220+
uint32_t defaultTimeSpan;
221+
if (object.HasMember("defaultTimeSpan") && object["defaultTimeSpan"].IsUint()) {
222+
defaultTimeSpan = object["defaultTimeSpan"].GetUint();
223+
} else {
224+
defaultTimeSpan = 30;
225+
}
226+
227+
timelines.push_back(std::make_shared<AmanTimeline>(targetFixes, viaFixes, destinationAirports, tagItems, property->name.GetString(), defaultTimeSpan));
197228
}
229+
}
198230

199-
timelines.push_back(std::make_shared<AmanTimeline>(targetFixes, viaFixes, destinationAirports, alias));
231+
auto makeSureWindowIsOpen = document.HasMember("openAutomatically") ? document["openAutomatically"].GetBool() : true;
232+
if (makeSureWindowIsOpen) {
233+
this->amanController->openWindow();
234+
}
235+
236+
// If only one timeline, open it automatically:
237+
if (timelines.size() == 1) {
238+
auto onlyTimelineId = timelines.at(0)->getIdentifier();
239+
if (!this->amanController->isTimelineActive(onlyTimelineId)) {
240+
this->amanController->toggleTimeline(onlyTimelineId);
241+
}
200242
}
201243
}
202244

@@ -250,8 +292,8 @@ std::shared_ptr<std::vector<std::shared_ptr<AmanTimeline>>> AmanPlugIn::getTimel
250292

251293
pAircraftList->clear();
252294
for each (auto finalFix in fixes) {
253-
auto var = getInboundsForFix(finalFix, viaFixes, timeline->getDestinationAirports());
254-
pAircraftList->insert(pAircraftList->end(), var.begin(), var.end());
295+
auto inbounds = getInboundsForFix(finalFix, viaFixes, timeline->getDestinationAirports());
296+
pAircraftList->insert(pAircraftList->end(), inbounds.begin(), inbounds.end());
255297
}
256298

257299
result->push_back(timeline);

Aman/AmanPlugIn.h

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class AmanPlugIn : public CPlugIn {
2626
std::string pluginDirectory;
2727

2828
virtual void OnTimer(int Counter);
29+
virtual bool OnCompileCommand(const char* sCommandLine);
2930

3031
bool hasCorrectDestination(CFlightPlanData fpd, std::vector<std::string> destinationAirports);
3132
int getFixIndexByName(CFlightPlanExtractedRoute extractedRoute, const std::string& fixName);

Aman/AmanTagItem.h

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#pragma once
2+
#include <string>
3+
4+
class TagItem {
5+
public:
6+
TagItem(const std::string& source, const std::string& defaultValue, uint32_t width, bool rightAligned, bool isViaFixIndicator) {
7+
this->source = source;
8+
this->width = width;
9+
this->rightAligned = rightAligned;
10+
this->defaultValue = defaultValue;
11+
this->isViaFixIndicator = isViaFixIndicator;
12+
}
13+
std::string getSource() { return source; };
14+
std::string getDefaultValue() { return defaultValue; };
15+
uint32_t getWidth() { return width; };
16+
bool isRightAligned() { return rightAligned; };
17+
bool getIsViaFixIndicator() { return isViaFixIndicator; };
18+
private:
19+
std::string source;
20+
std::string defaultValue;
21+
bool isViaFixIndicator;
22+
uint32_t width;
23+
bool rightAligned;
24+
};

Aman/AmanTimeline.cpp

+16-15
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,33 @@
22

33
#include <iterator>
44
#include <sstream>
5+
#include <numeric>
56

67
#include "AmanAircraft.h"
78
#include "AmanTimeline.h"
8-
9-
AmanTimeline::AmanTimeline(std::vector<std::string> fixes, std::vector<std::string> viaFixes, std::vector<std::string> destinations, const std::string& alias) {
9+
#include "AmanTagItem.h"
10+
11+
AmanTimeline::AmanTimeline(
12+
std::vector<std::string> fixes,
13+
std::vector<std::string> viaFixes,
14+
std::vector<std::string> destinations,
15+
std::vector<std::shared_ptr<TagItem>> tagItems,
16+
const std::string& alias,
17+
uint32_t defaultTimeSpan) {
1018
this->fixes = fixes;
1119
this->viaFixes = viaFixes;
1220
this->aircraftList = std::vector<AmanAircraft>();
1321
this->destinationAirports = destinations;
22+
this->tagItems = tagItems;
1423
this->alias = alias;
24+
this->defaultTimeSpan = defaultTimeSpan;
25+
26+
auto addWidth = [](uint32_t acc, std::shared_ptr<TagItem> tagItem) { return acc + tagItem->getWidth(); };
27+
this->width = std::accumulate(tagItems.begin(), tagItems.end(), 0, addWidth);
1528
}
1629

1730
std::string AmanTimeline::getIdentifier() {
18-
if(!alias.empty()) return alias;
19-
switch (fixes.size()) {
20-
case 1:
21-
return fixes.at(0);
22-
case 2:
23-
return fixes.at(0) + "/" + fixes.at(1);
24-
default:
25-
std::ostringstream fixesSs;
26-
copy(fixes.begin(), fixes.end(), std::ostream_iterator<std::string>(fixesSs, "/"));
27-
std::string output = fixesSs.str();
28-
output.pop_back(); // Remove last '/'
29-
return output;
30-
}
31+
return alias;
3132
}
3233

3334
bool AmanTimeline::isDual() { return fixes.size() == 2; }

0 commit comments

Comments
 (0)