separate label and aircraft label classes [in progress]
This commit is contained in:
parent
2c484dc5fd
commit
383081d0de
22
Aircraft.cpp
22
Aircraft.cpp
|
@ -30,34 +30,16 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "Aircraft.h"
|
#include "Aircraft.h"
|
||||||
|
#include "AircraftLabel.h"
|
||||||
|
|
||||||
Aircraft::Aircraft(uint32_t addr) {
|
Aircraft::Aircraft(uint32_t addr) {
|
||||||
this->addr = addr;
|
this->addr = addr;
|
||||||
prev_seen = 0;
|
prev_seen = 0;
|
||||||
|
|
||||||
x = 0;
|
|
||||||
y = 0;
|
|
||||||
cx = 0;
|
|
||||||
cy = 0;
|
|
||||||
w = 0;
|
|
||||||
h = 0;
|
|
||||||
target_w = 0;
|
|
||||||
target_h = 0;
|
|
||||||
|
|
||||||
opacity = 0;
|
|
||||||
target_opacity = 0;
|
|
||||||
|
|
||||||
ox = 0;
|
|
||||||
oy = 0;
|
|
||||||
dox = 0;
|
|
||||||
doy = 0;
|
|
||||||
ddox = 0;
|
|
||||||
ddoy = 0;
|
|
||||||
|
|
||||||
lon = 0;
|
lon = 0;
|
||||||
lat = 0;
|
lat = 0;
|
||||||
|
|
||||||
labelLevel = 0;
|
label = NULL;
|
||||||
|
|
||||||
next = NULL;
|
next = NULL;
|
||||||
}
|
}
|
||||||
|
|
16
Aircraft.h
16
Aircraft.h
|
@ -35,6 +35,8 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
||||||
|
class AircraftLabel;
|
||||||
|
|
||||||
class Aircraft {
|
class Aircraft {
|
||||||
public:
|
public:
|
||||||
uint32_t addr; // ICAO address
|
uint32_t addr; // ICAO address
|
||||||
|
@ -55,6 +57,9 @@ public:
|
||||||
std::vector <float> lonHistory, latHistory, headingHistory;
|
std::vector <float> lonHistory, latHistory, headingHistory;
|
||||||
std::vector <std::chrono::high_resolution_clock::time_point> timestampHistory;
|
std::vector <std::chrono::high_resolution_clock::time_point> timestampHistory;
|
||||||
|
|
||||||
|
|
||||||
|
AircraftLabel *label;
|
||||||
|
|
||||||
// float oldLon[TRAIL_LENGTH];
|
// float oldLon[TRAIL_LENGTH];
|
||||||
// float oldLat[TRAIL_LENGTH];
|
// float oldLat[TRAIL_LENGTH];
|
||||||
// float oldHeading[TRAIL_LENGTH];
|
// float oldHeading[TRAIL_LENGTH];
|
||||||
|
@ -69,11 +74,12 @@ public:
|
||||||
|
|
||||||
//// label stuff -> should go to aircraft icon class
|
//// label stuff -> should go to aircraft icon class
|
||||||
|
|
||||||
int x, y, cx, cy;
|
// int x, y, cx, cy;
|
||||||
float w, h, target_w, target_h;
|
int x, y;
|
||||||
float ox, oy, dox, doy, ddox, ddoy;
|
// float w, h, target_w, target_h;
|
||||||
float labelLevel;
|
// float ox, oy, dox, doy, ddox, ddoy;
|
||||||
float opacity, target_opacity;
|
// float labelLevel;
|
||||||
|
// float opacity, target_opacity;
|
||||||
|
|
||||||
/// methods
|
/// methods
|
||||||
|
|
||||||
|
|
424
AircraftLabel.cpp
Normal file
424
AircraftLabel.cpp
Normal file
|
@ -0,0 +1,424 @@
|
||||||
|
#include "AircraftLabel.h"
|
||||||
|
#include "Aircraft.h"
|
||||||
|
|
||||||
|
#include "SDL2/SDL2_gfxPrimitives.h"
|
||||||
|
|
||||||
|
|
||||||
|
static float sign(float x) {
|
||||||
|
return (x > 0) - (x < 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AircraftLabel::update() {
|
||||||
|
char flight[10] = "";
|
||||||
|
snprintf(flight,10," %s", p->flight);
|
||||||
|
|
||||||
|
flightLabel.setText(flight);
|
||||||
|
|
||||||
|
char alt[10] = "";
|
||||||
|
if (metric) {
|
||||||
|
snprintf(alt,10," %dm", (int) (p->altitude / 3.2828));
|
||||||
|
} else {
|
||||||
|
snprintf(alt,10," %d'", p->altitude);
|
||||||
|
}
|
||||||
|
|
||||||
|
altitudeLabel.setText(alt);
|
||||||
|
|
||||||
|
char speed[10] = "";
|
||||||
|
if (metric) {
|
||||||
|
snprintf(speed,10," %dkm/h", (int) (p->speed * 1.852));
|
||||||
|
} else {
|
||||||
|
snprintf(speed,10," %dmph", p->speed);
|
||||||
|
}
|
||||||
|
|
||||||
|
speedLabel.setText(speed);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AircraftLabel::clearAcceleration() {
|
||||||
|
ddx = 0;
|
||||||
|
ddy = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AircraftLabel::calculateForces(Aircraft *check_p) {
|
||||||
|
int p_left = x;
|
||||||
|
int p_right = x + w;
|
||||||
|
int p_top = y;
|
||||||
|
int p_bottom = y + h;
|
||||||
|
|
||||||
|
|
||||||
|
float boxmid_x = (float)(p_left + p_right) / 2.0f;
|
||||||
|
float boxmid_y = (float)(p_top + p_bottom) / 2.0f;
|
||||||
|
|
||||||
|
float offset_x = boxmid_x - p->x;
|
||||||
|
float offset_y = boxmid_y - p->y;
|
||||||
|
|
||||||
|
float target_length_x = attachment_dist + w / 2.0f;
|
||||||
|
float target_length_y = attachment_dist + h / 2.0f;
|
||||||
|
|
||||||
|
// stay icon_dist away from own icon
|
||||||
|
|
||||||
|
ddx -= sign(offset_x) * attachment_force * (fabs(offset_x) - target_length_x);
|
||||||
|
ddy -= sign(offset_y) * attachment_force * (fabs(offset_y) - target_length_y);
|
||||||
|
|
||||||
|
|
||||||
|
// // //screen edge
|
||||||
|
|
||||||
|
if(p_left < edge_margin) {
|
||||||
|
ddx += boundary_force * (float)(edge_margin - p_left);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(p_right > screen_width - edge_margin) {
|
||||||
|
ddx += boundary_force * (float)(screen_width - edge_margin - p_right);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(p_top < edge_margin) {
|
||||||
|
ddy += boundary_force * (float)(edge_margin - p_top);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(p_bottom > screen_height - edge_margin) {
|
||||||
|
ddy += boundary_force * (float)(screen_height - edge_margin - p_bottom);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float all_x = 0;
|
||||||
|
float all_y = 0;
|
||||||
|
int count = 0;
|
||||||
|
//check against other labels
|
||||||
|
|
||||||
|
float density_max = 0;
|
||||||
|
|
||||||
|
while(check_p) {
|
||||||
|
if(check_p->addr == p->addr) {
|
||||||
|
check_p = check_p->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!check_p->label) {
|
||||||
|
check_p = check_p->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//calculate density for label display level (inversely proportional to area of smallest box connecting this to neighbor)
|
||||||
|
float density = 1.0 / (0.001f + fabs(x - check_p->label->x) * fabs (x - check_p->label->y));
|
||||||
|
|
||||||
|
if(density > density_max) {
|
||||||
|
density_max = density;
|
||||||
|
}
|
||||||
|
|
||||||
|
density = 1.0 / (0.001f + fabs(x - check_p->x) * fabs(x - check_p->y));
|
||||||
|
|
||||||
|
if(density > density_max) {
|
||||||
|
density_max = density;
|
||||||
|
}
|
||||||
|
|
||||||
|
int check_left = check_p->label->x;
|
||||||
|
int check_right = check_p->label->x + check_p->label->w;
|
||||||
|
int check_top = check_p->label->y;
|
||||||
|
int check_bottom = check_p->label->y + check_p->label->h;
|
||||||
|
|
||||||
|
float icon_x = (float)check_p->x;
|
||||||
|
float icon_y = (float)check_p->y;
|
||||||
|
|
||||||
|
float checkboxmid_x = (float)(check_left + check_right) / 2.0f;
|
||||||
|
float checkboxmid_y = (float)(check_top + check_bottom) / 2.0f;
|
||||||
|
|
||||||
|
float offset_x = boxmid_x - checkboxmid_x;
|
||||||
|
float offset_y = boxmid_y - checkboxmid_y;
|
||||||
|
|
||||||
|
float target_length_x = label_dist + (float)(check_p->label->w + w) / 2.0f;
|
||||||
|
float target_length_y = label_dist + (float)(check_p->label->h + h) / 2.0f;
|
||||||
|
|
||||||
|
float x_mag = std::max(0.0f,(target_length_x - fabs(offset_x)));
|
||||||
|
float y_mag = std::max(0.0f,(target_length_y - fabs(offset_y)));
|
||||||
|
|
||||||
|
// stay at least label_dist away from other icons
|
||||||
|
|
||||||
|
if(x_mag > 0 && y_mag > 0) {
|
||||||
|
ddx += sign(offset_x) * label_force * x_mag;
|
||||||
|
ddy += sign(offset_y) * label_force * y_mag;
|
||||||
|
}
|
||||||
|
|
||||||
|
// stay at least icon_dist away from other icons
|
||||||
|
|
||||||
|
offset_x = boxmid_x - check_p->x;
|
||||||
|
offset_y = boxmid_y - check_p->y;
|
||||||
|
|
||||||
|
target_length_x = icon_dist + (float)check_p->label->w / 2.0f;
|
||||||
|
target_length_y = icon_dist + (float)check_p->label->h / 2.0f;
|
||||||
|
|
||||||
|
x_mag = std::max(0.0f,(target_length_x - fabs(offset_x)));
|
||||||
|
y_mag = std::max(0.0f,(target_length_y - fabs(offset_y)));
|
||||||
|
|
||||||
|
if(x_mag > 0 && y_mag > 0) {
|
||||||
|
ddx += sign(offset_x) * icon_force * x_mag;
|
||||||
|
ddy += sign(offset_y) * icon_force * y_mag;
|
||||||
|
}
|
||||||
|
|
||||||
|
all_x += sign(boxmid_x - checkboxmid_x);
|
||||||
|
all_y += sign(boxmid_y - checkboxmid_y);
|
||||||
|
|
||||||
|
count++;
|
||||||
|
|
||||||
|
check_p = check_p -> next;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// move away from others
|
||||||
|
ddx += density_force * all_x / count;
|
||||||
|
ddy += density_force * all_y / count;
|
||||||
|
|
||||||
|
// label drawlevel hysteresis
|
||||||
|
|
||||||
|
float density_mult = 100.0f;
|
||||||
|
float level_rate = 0.0005f;
|
||||||
|
|
||||||
|
if(labelLevel < -1.25f + density_mult * density_max) {
|
||||||
|
labelLevel += level_rate;
|
||||||
|
} else if (labelLevel > 0.5f + density_mult * density_max) {
|
||||||
|
labelLevel -= level_rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void AircraftLabel::applyForces() {
|
||||||
|
dx += ddx;
|
||||||
|
dy += ddy;
|
||||||
|
|
||||||
|
dx *= damping_force;
|
||||||
|
dy *= damping_force;
|
||||||
|
|
||||||
|
if(fabs(dx) > velocity_limit) {
|
||||||
|
dx = sign(dx) * velocity_limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(fabs(dy) > velocity_limit) {
|
||||||
|
dy = sign(dy) * velocity_limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(fabs(dx) < 0.01f) {
|
||||||
|
dx = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(fabs(dy) < 0.01f) {
|
||||||
|
dy = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
x += dx;
|
||||||
|
y += dy;
|
||||||
|
|
||||||
|
// x = p->cx + (int)round(p->ox);
|
||||||
|
// y = p->cy + (int)round(p->oy);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void AircraftLabel::draw(SDL_Renderer *renderer) {
|
||||||
|
//don't draw first time
|
||||||
|
if(x == 0 || y == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int totalWidth = 0;
|
||||||
|
int totalHeight = 0;
|
||||||
|
|
||||||
|
// int margin = 4 * screen_uiscale;
|
||||||
|
|
||||||
|
int margin = 4;
|
||||||
|
|
||||||
|
SDL_Rect outRect;
|
||||||
|
|
||||||
|
if(opacity == 0 && labelLevel < 2) {
|
||||||
|
target_opacity = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(opacity > 0 && labelLevel >= 2) {
|
||||||
|
target_opacity = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
opacity += 0.25f * (target_opacity - opacity);
|
||||||
|
|
||||||
|
if(opacity < 0.05f) {
|
||||||
|
opacity = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(w != 0) {
|
||||||
|
|
||||||
|
SDL_Color drawColor = style.labelLineColor;
|
||||||
|
|
||||||
|
drawColor.a = (int) (255.0f * opacity);
|
||||||
|
|
||||||
|
//this would need to be set in view (settable label level etc)
|
||||||
|
// if(p == selectedAircraft) {
|
||||||
|
// drawColor = style.selectedColor;
|
||||||
|
// }
|
||||||
|
|
||||||
|
int tick = 4;
|
||||||
|
|
||||||
|
int anchor_x, anchor_y, exit_x, exit_y;
|
||||||
|
|
||||||
|
if(x + w / 2 > p->x) {
|
||||||
|
anchor_x = x;
|
||||||
|
} else {
|
||||||
|
anchor_x = x + w;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(y + h / 2 > p->y) {
|
||||||
|
anchor_y = y - margin;
|
||||||
|
} else {
|
||||||
|
anchor_y = y + h + margin;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(abs(anchor_x - p->x) > abs(anchor_y - p->y)) {
|
||||||
|
exit_x = (anchor_x + p->x) / 2;
|
||||||
|
exit_y = anchor_y;
|
||||||
|
} else {
|
||||||
|
exit_x = anchor_x;
|
||||||
|
exit_y = (anchor_y + p->y) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
Sint16 vx[3] = {
|
||||||
|
static_cast<Sint16>(p->x),
|
||||||
|
static_cast<Sint16>(exit_x),
|
||||||
|
static_cast<Sint16>(anchor_x)};
|
||||||
|
|
||||||
|
Sint16 vy[3] = {
|
||||||
|
static_cast<Sint16>(p->y),
|
||||||
|
static_cast<Sint16>(exit_y),
|
||||||
|
static_cast<Sint16>(anchor_y)};
|
||||||
|
|
||||||
|
boxRGBA(renderer, x, y, x + w, y + h, 0, 0, 0, 255);
|
||||||
|
|
||||||
|
bezierRGBA(renderer, vx, vy, 3, 2, drawColor.r, drawColor.g, drawColor.b, drawColor.a);
|
||||||
|
|
||||||
|
//lineRGBA(renderer, x,y - margin, x + tick, y - margin, drawColor.r, drawColor.g, drawColor.b, drawColor.a);
|
||||||
|
lineRGBA(renderer, x,y - margin, x + w, y - margin, drawColor.r, drawColor.g, drawColor.b, drawColor.a);
|
||||||
|
lineRGBA(renderer, x,y - margin, x, y - margin + tick, drawColor.r, drawColor.g, drawColor.b, drawColor.a);
|
||||||
|
|
||||||
|
// lineRGBA(renderer, x + w, y - margin, x + w - tick, y - margin, drawColor.r, drawColor.g, drawColor.b, drawColor.a);
|
||||||
|
lineRGBA(renderer, x + w, y - margin, x + w, y - margin + tick, drawColor.r, drawColor.g, drawColor.b, drawColor.a);
|
||||||
|
|
||||||
|
//lineRGBA(renderer, x, y + h + margin, x + tick, y + h + margin, drawColor.r, drawColor.g, drawColor.b, drawColor.a);
|
||||||
|
lineRGBA(renderer, x, y + h + margin, x + w, y + h + margin, drawColor.r, drawColor.g, drawColor.b, drawColor.a);
|
||||||
|
lineRGBA(renderer, x, y + h + margin, x, y + h + margin - tick, drawColor.r, drawColor.g, drawColor.b, drawColor.a);
|
||||||
|
|
||||||
|
// lineRGBA(renderer, x + w, y + h + margin,x + w - tick, y + h + margin, drawColor.r, drawColor.g, drawColor.b, drawColor.a);
|
||||||
|
lineRGBA(renderer, x + w, y + h + margin,x + w, y + h + margin - tick, drawColor.r, drawColor.g, drawColor.b, drawColor.a);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if(labelLevel < 2 || p == selectedAircraft) {
|
||||||
|
//need externally settable label level
|
||||||
|
if(labelLevel < 2) {
|
||||||
|
// drawSignalMarks(p, x, y);
|
||||||
|
|
||||||
|
SDL_Color drawColor = style.labelColor;
|
||||||
|
drawColor.a = (int) (255.0f * opacity);
|
||||||
|
|
||||||
|
flightLabel.setFGColor(drawColor);
|
||||||
|
flightLabel.draw(renderer);
|
||||||
|
// outRect = drawString(flight, x, y, mapBoldFont, drawColor);
|
||||||
|
outRect = flightLabel.getRect();
|
||||||
|
|
||||||
|
totalWidth = std::max(totalWidth,outRect.w);
|
||||||
|
totalHeight += outRect.h;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// if(labelLevel < 1 || p == selectedAircraft) {
|
||||||
|
if(labelLevel < 1) {
|
||||||
|
SDL_Color drawColor = style.subLabelColor;
|
||||||
|
drawColor.a = (int) (255.0f * opacity);
|
||||||
|
|
||||||
|
// drawStringBG(alt, x, y + currentLine * mapFontHeight, mapFont, style.subLabelColor, style.labelBackground);
|
||||||
|
// outRect = drawString(alt, x, y + totalHeight, mapFont, drawColor);
|
||||||
|
altitudeLabel.setFGColor(drawColor);
|
||||||
|
altitudeLabel.draw(renderer);
|
||||||
|
outRect = altitudeLabel.getRect();
|
||||||
|
|
||||||
|
totalWidth = std::max(totalWidth,outRect.w);
|
||||||
|
totalHeight += outRect.h;
|
||||||
|
|
||||||
|
|
||||||
|
// drawStringBG(speed, x, y + currentLine * mapFontHeight, mapFont, style.subLabelColor, style.labelBackground);
|
||||||
|
// outRect = drawString(speed, x, y + totalHeight, mapFont, drawColor);
|
||||||
|
speedLabel.setFGColor(drawColor);
|
||||||
|
speedLabel.draw(renderer);
|
||||||
|
outRect = speedLabel.getRect();
|
||||||
|
|
||||||
|
totalWidth = std::max(totalWidth,outRect.w);
|
||||||
|
totalHeight += outRect.h;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//label debug
|
||||||
|
// char debug[25] = "";
|
||||||
|
// snprintf(debug,25,"%1.2f", p->labelLevel);
|
||||||
|
// drawString(debug, p->x, p->y + totalHeight, mapFont, style.red);
|
||||||
|
|
||||||
|
// if(maxCharCount > 1) {
|
||||||
|
|
||||||
|
// Sint16 vx[4] = {
|
||||||
|
// static_cast<Sint16>(p->cx),
|
||||||
|
// static_cast<Sint16>(p->cx + (p->x - p->cx) / 2),
|
||||||
|
// static_cast<Sint16>(p->x),
|
||||||
|
// static_cast<Sint16>(p->x)};
|
||||||
|
|
||||||
|
// Sint16 vy[4] = {
|
||||||
|
// static_cast<Sint16>(p->cy),
|
||||||
|
// static_cast<Sint16>(p->cy + (p->y - p->cy) / 2),
|
||||||
|
// static_cast<Sint16>(p->y - mapFontHeight),
|
||||||
|
// static_cast<Sint16>(p->y)};
|
||||||
|
|
||||||
|
// if(p->cy > p->y + currentLine * mapFontHeight) {
|
||||||
|
// vy[2] = p->y + currentLine * mapFontHeight + mapFontHeight;
|
||||||
|
// vy[3] = p->y + currentLine * mapFontHeight;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// bezierRGBA(renderer,vx,vy,4,2,style.labelLineColor.r,style.labelLineColor.g,style.labelLineColor.b,SDL_ALPHA_OPAQUE);
|
||||||
|
|
||||||
|
|
||||||
|
// lineRGBA(renderer,p->x,p->y,p->x,p->y+currentLine*mapFontHeight,style.labelLineColor.r,style.labelLineColor.g,style.labelLineColor.b,SDL_ALPHA_OPAQUE);
|
||||||
|
// }
|
||||||
|
|
||||||
|
target_w = totalWidth;
|
||||||
|
target_h = totalHeight;
|
||||||
|
|
||||||
|
w += 0.25f * (target_w - w);
|
||||||
|
h += 0.25f * (target_h - h);
|
||||||
|
|
||||||
|
if(w < 0.05f) {
|
||||||
|
w = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(h < 0.05f) {
|
||||||
|
h = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AircraftLabel::AircraftLabel(Aircraft *p, bool metric, int screen_width, int screen_height, TTF_Font *font) {
|
||||||
|
this->p = p;
|
||||||
|
|
||||||
|
this->metric = metric;
|
||||||
|
|
||||||
|
x = p->x;
|
||||||
|
y = p->y + 20; //*screen_uiscale
|
||||||
|
w = 0;
|
||||||
|
h = 0;
|
||||||
|
target_w = 0;
|
||||||
|
target_h = 0;
|
||||||
|
|
||||||
|
opacity = 0;
|
||||||
|
target_opacity = 0;
|
||||||
|
|
||||||
|
dx = 0;
|
||||||
|
dy = 0;
|
||||||
|
ddx = 0;
|
||||||
|
ddy = 0;
|
||||||
|
|
||||||
|
this->screen_width = screen_width;
|
||||||
|
this->screen_height = screen_height;
|
||||||
|
|
||||||
|
labelLevel = 0;
|
||||||
|
|
||||||
|
flightLabel.setFont(font);
|
||||||
|
altitudeLabel.setFont(font);
|
||||||
|
speedLabel.setFont(font);
|
||||||
|
}
|
70
AircraftLabel.h
Normal file
70
AircraftLabel.h
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include "SDL2/SDL_ttf.h"
|
||||||
|
|
||||||
|
#include "Label.h"
|
||||||
|
#include "Style.h"
|
||||||
|
|
||||||
|
class Aircraft;
|
||||||
|
|
||||||
|
|
||||||
|
class AircraftLabel {
|
||||||
|
public:
|
||||||
|
void update();
|
||||||
|
void clearAcceleration();
|
||||||
|
void calculateForces(Aircraft *check_p);
|
||||||
|
void applyForces();
|
||||||
|
|
||||||
|
void draw(SDL_Renderer *renderer);
|
||||||
|
|
||||||
|
AircraftLabel(Aircraft *p, bool metric, int screen_width, int screen_height, TTF_Font *font);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Aircraft *p;
|
||||||
|
|
||||||
|
Label flightLabel;
|
||||||
|
Label altitudeLabel;
|
||||||
|
Label speedLabel;
|
||||||
|
|
||||||
|
int labelLevel;
|
||||||
|
|
||||||
|
bool metric;
|
||||||
|
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
float w;
|
||||||
|
float h;
|
||||||
|
|
||||||
|
float target_w;
|
||||||
|
float target_h;
|
||||||
|
|
||||||
|
float dx;
|
||||||
|
float dy;
|
||||||
|
float ddx;
|
||||||
|
float ddy;
|
||||||
|
|
||||||
|
float opacity;
|
||||||
|
float target_opacity;
|
||||||
|
|
||||||
|
float pressure;
|
||||||
|
|
||||||
|
int screen_width;
|
||||||
|
int screen_height;
|
||||||
|
|
||||||
|
///////////
|
||||||
|
|
||||||
|
float label_force = 0.001f;
|
||||||
|
float label_dist = 2.0f;
|
||||||
|
float density_force = 0.05f;
|
||||||
|
float attachment_force = 0.0015f;
|
||||||
|
float attachment_dist = 10.0f;
|
||||||
|
float icon_force = 0.001f;
|
||||||
|
float icon_dist = 15.0f;
|
||||||
|
float boundary_force = 0.01f;
|
||||||
|
float damping_force = 0.85f;
|
||||||
|
float velocity_limit = 2.0f;
|
||||||
|
float edge_margin = 15.0f;
|
||||||
|
|
||||||
|
Style style;
|
||||||
|
};
|
78
Label.cpp
Normal file
78
Label.cpp
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
#include "Label.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
void Label::draw(SDL_Renderer *renderer) {
|
||||||
|
SDL_Rect rect = getRect();
|
||||||
|
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface);
|
||||||
|
SDL_RenderCopy(renderer, texture, NULL, &rect);
|
||||||
|
SDL_DestroyTexture(texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Label::makeSurface() {
|
||||||
|
// if(BGColor.a = 0) {
|
||||||
|
surface = TTF_RenderUTF8_Solid(font, text.c_str(), FGColor);
|
||||||
|
// } else {
|
||||||
|
// surface = TTF_RenderUTF8_Shaded(font, text.c_str(), FGColor, BGColor);
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
if (surface == NULL)
|
||||||
|
{
|
||||||
|
printf("Couldn't create surface for String %s: %s\n", text.c_str(), SDL_GetError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SDL_Rect Label::getRect() {
|
||||||
|
SDL_Rect rect = {0,0,0,0};
|
||||||
|
|
||||||
|
if(!text.length()) {
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(surface == NULL) {
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
rect.x = x;
|
||||||
|
rect.y = y;
|
||||||
|
rect.w = surface->w;
|
||||||
|
rect.h = surface->h;
|
||||||
|
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Label::setText(std::string text) {
|
||||||
|
this->text = text;
|
||||||
|
makeSurface();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Label::setPosition(int x, int y) {
|
||||||
|
this->x = x;
|
||||||
|
this->y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Label::setFont(TTF_Font *font) {
|
||||||
|
this->font = font;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Label::setFGColor(SDL_Color color) {
|
||||||
|
this->FGColor = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Label::setBGColor(SDL_Color color) {
|
||||||
|
this->BGColor = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
Label::Label() {
|
||||||
|
BGColor = {0, 0, 0, 0};
|
||||||
|
surface = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Label::~Label() {
|
||||||
|
SDL_FreeSurface(surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
32
Label.h
Normal file
32
Label.h
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
|
||||||
|
#include "SDL2/SDL.h"
|
||||||
|
#include "SDL2/SDL_ttf.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class Label {
|
||||||
|
public:
|
||||||
|
void draw(SDL_Renderer *renderer);
|
||||||
|
|
||||||
|
void setText(std::string text);
|
||||||
|
void setPosition(int x, int y);
|
||||||
|
void setFont(TTF_Font *font);
|
||||||
|
void setFGColor(SDL_Color color);
|
||||||
|
void setBGColor(SDL_Color color);
|
||||||
|
|
||||||
|
SDL_Rect getRect();
|
||||||
|
|
||||||
|
Label();
|
||||||
|
~Label();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void makeSurface();
|
||||||
|
|
||||||
|
|
||||||
|
std::string text;
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
TTF_Font *font;
|
||||||
|
SDL_Color FGColor;
|
||||||
|
SDL_Color BGColor;
|
||||||
|
SDL_Surface *surface;
|
||||||
|
};
|
8
Makefile
8
Makefile
|
@ -3,8 +3,8 @@
|
||||||
# sure that the variable PREFIX is defined, e.g. make PREFIX=/usr/local
|
# sure that the variable PREFIX is defined, e.g. make PREFIX=/usr/local
|
||||||
#
|
#
|
||||||
|
|
||||||
CXXFLAGS=-O2 -std=c++11
|
CXXFLAGS=-O2 -std=c++11 -g
|
||||||
LIBS= -lm -lSDL2 -lSDL2_ttf -lSDL2_gfx
|
LIBS= -lm -lSDL2 -lSDL2_ttf -lSDL2_gfx -g
|
||||||
CXX=g++
|
CXX=g++
|
||||||
|
|
||||||
all: viz1090
|
all: viz1090
|
||||||
|
@ -12,8 +12,8 @@ all: viz1090
|
||||||
%.o: %.c %.cpp
|
%.o: %.c %.cpp
|
||||||
$(CXX) $(CXXFLAGS) $(EXTRACFLAGS) -c $<
|
$(CXX) $(CXXFLAGS) $(EXTRACFLAGS) -c $<
|
||||||
|
|
||||||
viz1090: viz1090.o AppData.o AircraftList.o Aircraft.o anet.o interactive.o mode_ac.o mode_s.o net_io.o Input.o View.o Map.o parula.o monokai.o
|
viz1090: viz1090.o AppData.o AircraftList.o Aircraft.o Label.o AircraftLabel.o anet.o interactive.o mode_ac.o mode_s.o net_io.o Input.o View.o Map.o parula.o monokai.o
|
||||||
$(CXX) -o viz1090 viz1090.o AppData.o AircraftList.o Aircraft.o anet.o interactive.o mode_ac.o mode_s.o net_io.o Input.o View.o Map.o parula.o monokai.o $(LIBS) $(LDFLAGS)
|
$(CXX) -o viz1090 viz1090.o AppData.o AircraftList.o Aircraft.o Label.o AircraftLabel.o anet.o interactive.o mode_ac.o mode_s.o net_io.o Input.o View.o Map.o parula.o monokai.o $(LIBS) $(LDFLAGS)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o viz1090
|
rm -f *.o viz1090
|
||||||
|
|
4
Map.cpp
4
Map.cpp
|
@ -342,7 +342,7 @@ Map::Map() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// std::cout << "[" << x << "," << y << "] " << assemble << "\n";
|
// std::cout << "[" << x << "," << y << "] " << assemble << "\n";
|
||||||
Label *label = new Label(lon,lat,assemble);
|
MapLabel *label = new MapLabel(lon,lat,assemble);
|
||||||
mapnames.push_back(label);
|
mapnames.push_back(label);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -371,7 +371,7 @@ Map::Map() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// std::cout << "[" << x << "," << y << "] " << assemble << "\n";
|
// std::cout << "[" << x << "," << y << "] " << assemble << "\n";
|
||||||
Label *label = new Label(lon,lat,assemble);
|
MapLabel *label = new MapLabel(lon,lat,assemble);
|
||||||
airportnames.push_back(label);
|
airportnames.push_back(label);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
10
Map.h
10
Map.h
|
@ -40,16 +40,16 @@ typedef struct Point{
|
||||||
float lon;
|
float lon;
|
||||||
} Point;
|
} Point;
|
||||||
|
|
||||||
typedef struct Label{
|
typedef struct MapLabel{
|
||||||
Point location;
|
Point location;
|
||||||
std::string text;
|
std::string text;
|
||||||
|
|
||||||
Label(float lon, float lat, std::string text) {
|
MapLabel(float lon, float lat, std::string text) {
|
||||||
this->location.lon = lon;
|
this->location.lon = lon;
|
||||||
this->location.lat = lat;
|
this->location.lat = lat;
|
||||||
this->text = text;
|
this->text = text;
|
||||||
}
|
}
|
||||||
} Label;
|
} MapLabel;
|
||||||
|
|
||||||
typedef struct Line{
|
typedef struct Line{
|
||||||
float lat_min;
|
float lat_min;
|
||||||
|
@ -125,8 +125,8 @@ public:
|
||||||
std::vector<Line*> getLinesRecursive(QuadTree *tree, float screen_lat_min, float screen_lat_max, float screen_lon_min, float screen_lon_max);
|
std::vector<Line*> getLinesRecursive(QuadTree *tree, float screen_lat_min, float screen_lat_max, float screen_lon_min, float screen_lon_max);
|
||||||
std::vector<Line*> getLines(float screen_lat_min, float screen_lat_max, float screen_lon_min, float screen_lon_max);
|
std::vector<Line*> getLines(float screen_lat_min, float screen_lat_max, float screen_lon_min, float screen_lon_max);
|
||||||
|
|
||||||
std::vector<Label*> mapnames;
|
std::vector<MapLabel*> mapnames;
|
||||||
std::vector<Label*> airportnames;
|
std::vector<MapLabel*> airportnames;
|
||||||
|
|
||||||
Map();
|
Map();
|
||||||
|
|
||||||
|
|
94
Style.h
Normal file
94
Style.h
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
#ifndef STYLE_H
|
||||||
|
#define STYLE_H
|
||||||
|
|
||||||
|
#include "SDL2/SDL.h"
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// This should go to a full theming class
|
||||||
|
//
|
||||||
|
typedef struct Style {
|
||||||
|
SDL_Color backgroundColor;
|
||||||
|
|
||||||
|
SDL_Color selectedColor;
|
||||||
|
SDL_Color planeColor;
|
||||||
|
SDL_Color planeGoneColor;
|
||||||
|
SDL_Color trailColor;
|
||||||
|
|
||||||
|
SDL_Color geoColor;
|
||||||
|
SDL_Color airportColor;
|
||||||
|
|
||||||
|
SDL_Color labelColor;
|
||||||
|
SDL_Color labelLineColor;
|
||||||
|
SDL_Color subLabelColor;
|
||||||
|
SDL_Color labelBackground;
|
||||||
|
|
||||||
|
SDL_Color scaleBarColor;
|
||||||
|
SDL_Color buttonColor;
|
||||||
|
SDL_Color buttonBackground;
|
||||||
|
SDL_Color buttonOutline;
|
||||||
|
|
||||||
|
SDL_Color clickColor;
|
||||||
|
|
||||||
|
SDL_Color black;
|
||||||
|
SDL_Color white;
|
||||||
|
SDL_Color red;
|
||||||
|
SDL_Color green;
|
||||||
|
SDL_Color blue;
|
||||||
|
|
||||||
|
//
|
||||||
|
// todo separate style stuff
|
||||||
|
//
|
||||||
|
|
||||||
|
Style() {
|
||||||
|
|
||||||
|
SDL_Color pink = {249,38,114,255};
|
||||||
|
|
||||||
|
SDL_Color purple = {85, 0, 255,255};
|
||||||
|
SDL_Color purple_dark = {33, 0, 122,255};
|
||||||
|
|
||||||
|
SDL_Color blue = {102,217,239,255};
|
||||||
|
SDL_Color blue_dark = {102,217,239,255};
|
||||||
|
|
||||||
|
SDL_Color green = {0,255,234,255};
|
||||||
|
SDL_Color green_dark = {24,100,110,255};
|
||||||
|
|
||||||
|
SDL_Color yellow = {216,255,0,255};
|
||||||
|
SDL_Color yellow_dark = {90,133,50,255};
|
||||||
|
|
||||||
|
SDL_Color orange = {253,151,31,255};
|
||||||
|
SDL_Color grey_light = {196,196,196,255};
|
||||||
|
SDL_Color grey = {127,127,127,255};
|
||||||
|
SDL_Color grey_dark = {64,64,64,255};
|
||||||
|
|
||||||
|
black = {0,0,0,255};
|
||||||
|
white = {255,255,255,255};
|
||||||
|
red = {255,0,0,255};
|
||||||
|
green = {0,255,0,255};
|
||||||
|
blue = {0,0,255,255};
|
||||||
|
|
||||||
|
|
||||||
|
backgroundColor = black;
|
||||||
|
|
||||||
|
selectedColor = pink;
|
||||||
|
planeColor = yellow;
|
||||||
|
planeGoneColor = grey;
|
||||||
|
trailColor = yellow_dark;
|
||||||
|
|
||||||
|
geoColor = purple_dark;
|
||||||
|
airportColor = purple;
|
||||||
|
|
||||||
|
labelColor = white;
|
||||||
|
labelLineColor = grey_dark;
|
||||||
|
subLabelColor = grey;
|
||||||
|
labelBackground = black;
|
||||||
|
scaleBarColor = grey_light;
|
||||||
|
buttonColor = grey_light;
|
||||||
|
buttonBackground = black;
|
||||||
|
buttonOutline = grey_light;
|
||||||
|
|
||||||
|
clickColor = grey;
|
||||||
|
}
|
||||||
|
} Style;
|
||||||
|
|
||||||
|
#endif
|
73
Text.cpp
Normal file
73
Text.cpp
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
#include "SDL2/SDL2_gfxPrimitives.h"
|
||||||
|
|
||||||
|
#include "Text.h"
|
||||||
|
|
||||||
|
SDL_Rect Text::drawString(std::string text, int x, int y, TTF_Font *font, SDL_Color color)
|
||||||
|
{
|
||||||
|
SDL_Rect dest = {0,0,0,0};
|
||||||
|
|
||||||
|
if(!text.length()) {
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Surface *surface;
|
||||||
|
|
||||||
|
surface = TTF_RenderUTF8_Solid(font, text.c_str(), color);
|
||||||
|
|
||||||
|
if (surface == NULL)
|
||||||
|
{
|
||||||
|
printf("Couldn't create String %s: %s\n", text.c_str(), SDL_GetError());
|
||||||
|
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
dest.x = x;
|
||||||
|
dest.y = y;
|
||||||
|
dest.w = surface->w;
|
||||||
|
dest.h = surface->h;
|
||||||
|
|
||||||
|
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface);
|
||||||
|
SDL_RenderCopy(renderer, texture, NULL, &dest);
|
||||||
|
SDL_DestroyTexture(texture);
|
||||||
|
SDL_FreeSurface(surface);
|
||||||
|
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Rect Text::drawStringBG(std::string text, int x, int y, TTF_Font *font, SDL_Color color, SDL_Color bgColor) {
|
||||||
|
SDL_Rect dest = {0,0,0,0};
|
||||||
|
|
||||||
|
if(!text.length()) {
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Surface *surface;
|
||||||
|
|
||||||
|
surface = TTF_RenderUTF8_Shaded(font, text.c_str(), color, bgColor);
|
||||||
|
|
||||||
|
if (surface == NULL)
|
||||||
|
{
|
||||||
|
printf("Couldn't create String %s: %s\n", text.c_str(), SDL_GetError());
|
||||||
|
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
dest.x = x;
|
||||||
|
dest.y = y;
|
||||||
|
dest.w = surface->w;
|
||||||
|
dest.h = surface->h;
|
||||||
|
|
||||||
|
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface);
|
||||||
|
SDL_RenderCopy(renderer, texture, NULL, &dest);
|
||||||
|
SDL_DestroyTexture(texture);
|
||||||
|
SDL_FreeSurface(surface);
|
||||||
|
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// check if text has changed and surface exists
|
||||||
|
// redraw existing surface
|
||||||
|
// or make new surface
|
||||||
|
// for BG, draw bg size of surface
|
||||||
|
// draw surface
|
610
View.cpp
610
View.cpp
|
@ -37,6 +37,8 @@
|
||||||
|
|
||||||
#include "View.h"
|
#include "View.h"
|
||||||
|
|
||||||
|
#include "AircraftLabel.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
|
@ -55,10 +57,6 @@ static float elapsed_s(std::chrono::high_resolution_clock::time_point ref) {
|
||||||
return (fseconds { now() - ref}).count();
|
return (fseconds { now() - ref}).count();
|
||||||
}
|
}
|
||||||
|
|
||||||
static float sign(float x) {
|
|
||||||
return (x > 0) - (x < 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static float clamp(float in, float min, float max) {
|
static float clamp(float in, float min, float max) {
|
||||||
float out = in;
|
float out = in;
|
||||||
|
|
||||||
|
@ -225,9 +223,6 @@ int View::outOfBounds(int x, int y, int left, int top, int right, int bottom) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Font stuff
|
|
||||||
//
|
|
||||||
|
|
||||||
TTF_Font* View::loadFont(const char *name, int size)
|
TTF_Font* View::loadFont(const char *name, int size)
|
||||||
{
|
{
|
||||||
|
@ -251,6 +246,28 @@ void View::closeFont(TTF_Font *font)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void View::font_init() {
|
||||||
|
mapFont = loadFont("font/TerminusTTF-4.46.0.ttf", 12 * screen_uiscale);
|
||||||
|
mapBoldFont = loadFont("font/TerminusTTF-Bold-4.46.0.ttf", 12 * screen_uiscale);
|
||||||
|
|
||||||
|
listFont = loadFont("font/TerminusTTF-4.46.0.ttf", 12 * screen_uiscale);
|
||||||
|
|
||||||
|
messageFont = loadFont("font/TerminusTTF-Bold-4.46.0.ttf", 12 * screen_uiscale);
|
||||||
|
labelFont = loadFont("font/TerminusTTF-Bold-4.46.0.ttf", 12 * screen_uiscale);
|
||||||
|
|
||||||
|
mapFontWidth = 5 * screen_uiscale;
|
||||||
|
mapFontHeight = 12 * screen_uiscale;
|
||||||
|
|
||||||
|
messageFontWidth = 6 * screen_uiscale;
|
||||||
|
messageFontHeight = 12 * screen_uiscale;
|
||||||
|
|
||||||
|
labelFontWidth = 6 * screen_uiscale;
|
||||||
|
labelFontHeight = 12 * screen_uiscale;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// SDL Utils
|
// SDL Utils
|
||||||
//
|
//
|
||||||
|
@ -300,90 +317,9 @@ void View::SDL_init() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void View::font_init() {
|
|
||||||
mapFont = loadFont("font/TerminusTTF-4.46.0.ttf", 12 * screen_uiscale);
|
|
||||||
mapBoldFont = loadFont("font/TerminusTTF-Bold-4.46.0.ttf", 12 * screen_uiscale);
|
|
||||||
|
|
||||||
listFont = loadFont("font/TerminusTTF-4.46.0.ttf", 12 * screen_uiscale);
|
|
||||||
|
|
||||||
messageFont = loadFont("font/TerminusTTF-Bold-4.46.0.ttf", 12 * screen_uiscale);
|
|
||||||
labelFont = loadFont("font/TerminusTTF-Bold-4.46.0.ttf", 12 * screen_uiscale);
|
|
||||||
|
|
||||||
mapFontWidth = 5 * screen_uiscale;
|
|
||||||
mapFontHeight = 12 * screen_uiscale;
|
|
||||||
|
|
||||||
messageFontWidth = 6 * screen_uiscale;
|
|
||||||
messageFontHeight = 12 * screen_uiscale;
|
|
||||||
|
|
||||||
labelFontWidth = 6 * screen_uiscale;
|
|
||||||
labelFontHeight = 12 * screen_uiscale;
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_Rect View::drawString(std::string text, int x, int y, TTF_Font *font, SDL_Color color)
|
|
||||||
{
|
|
||||||
SDL_Rect dest = {0,0,0,0};
|
|
||||||
|
|
||||||
if(!text.length()) {
|
|
||||||
return dest;
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_Surface *surface;
|
|
||||||
|
|
||||||
surface = TTF_RenderUTF8_Solid(font, text.c_str(), color);
|
|
||||||
|
|
||||||
if (surface == NULL)
|
|
||||||
{
|
|
||||||
printf("Couldn't create String %s: %s\n", text.c_str(), SDL_GetError());
|
|
||||||
|
|
||||||
return dest;
|
|
||||||
}
|
|
||||||
|
|
||||||
dest.x = x;
|
|
||||||
dest.y = y;
|
|
||||||
dest.w = surface->w;
|
|
||||||
dest.h = surface->h;
|
|
||||||
|
|
||||||
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface);
|
|
||||||
SDL_RenderCopy(renderer, texture, NULL, &dest);
|
|
||||||
SDL_DestroyTexture(texture);
|
|
||||||
SDL_FreeSurface(surface);
|
|
||||||
|
|
||||||
return dest;
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_Rect View::drawStringBG(std::string text, int x, int y, TTF_Font *font, SDL_Color color, SDL_Color bgColor) {
|
|
||||||
SDL_Rect dest = {0,0,0,0};
|
|
||||||
|
|
||||||
if(!text.length()) {
|
|
||||||
return dest;
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_Surface *surface;
|
|
||||||
|
|
||||||
surface = TTF_RenderUTF8_Shaded(font, text.c_str(), color, bgColor);
|
|
||||||
|
|
||||||
if (surface == NULL)
|
|
||||||
{
|
|
||||||
printf("Couldn't create String %s: %s\n", text.c_str(), SDL_GetError());
|
|
||||||
|
|
||||||
return dest;
|
|
||||||
}
|
|
||||||
|
|
||||||
dest.x = x;
|
|
||||||
dest.y = y;
|
|
||||||
dest.w = surface->w;
|
|
||||||
dest.h = surface->h;
|
|
||||||
|
|
||||||
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface);
|
|
||||||
SDL_RenderCopy(renderer, texture, NULL, &dest);
|
|
||||||
SDL_DestroyTexture(texture);
|
|
||||||
SDL_FreeSurface(surface);
|
|
||||||
|
|
||||||
return dest;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Status boxes
|
// Status boxes -> move to separate class
|
||||||
//
|
//
|
||||||
|
|
||||||
void View::drawStatusBox(int *left, int *top, std::string label, std::string message, SDL_Color color) {
|
void View::drawStatusBox(int *left, int *top, std::string label, std::string message, SDL_Color color) {
|
||||||
|
@ -410,10 +346,18 @@ void View::drawStatusBox(int *left, int *top, std::string label, std::string mes
|
||||||
roundedRectangleRGBA(renderer, *left, *top, *left + labelWidth + messageWidth, *top + messageFontHeight, ROUND_RADIUS,color.r, color.g, color.b, SDL_ALPHA_OPAQUE);
|
roundedRectangleRGBA(renderer, *left, *top, *left + labelWidth + messageWidth, *top + messageFontHeight, ROUND_RADIUS,color.r, color.g, color.b, SDL_ALPHA_OPAQUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
drawString(label, *left + labelFontWidth/2, *top, labelFont, style.buttonBackground);
|
Label currentLabel;
|
||||||
|
currentLabel.setFont(labelFont);
|
||||||
//message
|
currentLabel.setFGColor(style.buttonBackground);
|
||||||
drawString(message, *left + labelWidth + messageFontWidth/2, *top, messageFont, color);
|
currentLabel.setPosition(*left + labelFontWidth/2, *top);
|
||||||
|
currentLabel.setText(label);
|
||||||
|
currentLabel.draw(renderer);
|
||||||
|
|
||||||
|
currentLabel.setFont(messageFont);
|
||||||
|
currentLabel.setFGColor(color);
|
||||||
|
currentLabel.setPosition(*left + labelWidth + messageFontWidth/2, *top);
|
||||||
|
currentLabel.setText(message);
|
||||||
|
currentLabel.draw(renderer);
|
||||||
|
|
||||||
*left = *left + labelWidth + messageWidth + PAD;
|
*left = *left + labelWidth + messageWidth + PAD;
|
||||||
}
|
}
|
||||||
|
@ -635,8 +579,13 @@ void View::drawScaleBars()
|
||||||
snprintf(scaleLabel,13,"%dmi", (int)pow(10,scalePower));
|
snprintf(scaleLabel,13,"%dmi", (int)pow(10,scalePower));
|
||||||
}
|
}
|
||||||
|
|
||||||
drawString(scaleLabel, 10+scaleBarDist, 15*screen_uiscale, mapFont, style.scaleBarColor);
|
Label currentLabel;
|
||||||
|
currentLabel.setFont(mapFont);
|
||||||
|
currentLabel.setFGColor(style.scaleBarColor);
|
||||||
|
currentLabel.setPosition(10+scaleBarDist, 15*screen_uiscale);
|
||||||
|
currentLabel.setText(scaleLabel);
|
||||||
|
currentLabel.draw(renderer);
|
||||||
|
|
||||||
scalePower++;
|
scalePower++;
|
||||||
scaleBarDist = screenDist((float)pow(10,scalePower));
|
scaleBarDist = screenDist((float)pow(10,scalePower));
|
||||||
}
|
}
|
||||||
|
@ -740,7 +689,11 @@ void View::drawLinesRecursive(QuadTree *tree, float screen_lat_min, float screen
|
||||||
|
|
||||||
void View::drawPlaceNames() {
|
void View::drawPlaceNames() {
|
||||||
|
|
||||||
for(std::vector<Label*>::iterator label = map.mapnames.begin(); label != map.mapnames.end(); ++label) {
|
Label currentLabel;
|
||||||
|
currentLabel.setFont(mapFont);
|
||||||
|
currentLabel.setFGColor(style.geoColor);
|
||||||
|
|
||||||
|
for(std::vector<MapLabel*>::iterator label = map.mapnames.begin(); label != map.mapnames.end(); ++label) {
|
||||||
float dx, dy;
|
float dx, dy;
|
||||||
int x,y;
|
int x,y;
|
||||||
|
|
||||||
|
@ -751,10 +704,12 @@ void View::drawPlaceNames() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
drawString((*label)->text, x, y, mapFont, style.geoColor);
|
currentLabel.setText((*label)->text);
|
||||||
|
currentLabel.setPosition(x,y);
|
||||||
|
currentLabel.draw(renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(std::vector<Label*>::iterator label = map.airportnames.begin(); label != map.airportnames.end(); ++label) {
|
for(std::vector<MapLabel*>::iterator label = map.airportnames.begin(); label != map.airportnames.end(); ++label) {
|
||||||
float dx, dy;
|
float dx, dy;
|
||||||
int x,y;
|
int x,y;
|
||||||
|
|
||||||
|
@ -765,7 +720,9 @@ void View::drawPlaceNames() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
drawString((*label)->text, x, y, listFont, style.airportColor);
|
currentLabel.setText((*label)->text);
|
||||||
|
currentLabel.setPosition(x,y);
|
||||||
|
currentLabel.draw(renderer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -879,429 +836,45 @@ void View::drawSignalMarks(Aircraft *p, int x, int y) {
|
||||||
|
|
||||||
|
|
||||||
void View::drawPlaneText(Aircraft *p) {
|
void View::drawPlaneText(Aircraft *p) {
|
||||||
|
if(!p->label) {
|
||||||
//don't draw first time
|
p->label = new AircraftLabel(p,metric,screen_width, screen_height, mapFont);
|
||||||
if(p->x == 0 || p->y == 0) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int charCount;
|
p->label->update();
|
||||||
int totalWidth = 0;
|
p->label->draw(renderer);
|
||||||
int totalHeight = 0;
|
|
||||||
|
|
||||||
int margin = 4 * screen_uiscale;
|
|
||||||
|
|
||||||
SDL_Rect outRect;
|
|
||||||
|
|
||||||
if(p->opacity == 0 && p->labelLevel < 2) {
|
|
||||||
p->target_opacity = 1.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(p->opacity > 0 && p->labelLevel >= 2) {
|
|
||||||
p->target_opacity = 0.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
p->opacity += 0.25f * (p->target_opacity - p->opacity);
|
|
||||||
|
|
||||||
if(p->opacity < 0.05f) {
|
|
||||||
p->opacity = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(p->w != 0) {
|
|
||||||
|
|
||||||
SDL_Color drawColor = style.labelLineColor;
|
|
||||||
|
|
||||||
drawColor.a = (int) (255.0f * p->opacity);
|
|
||||||
|
|
||||||
if(p == selectedAircraft) {
|
|
||||||
drawColor = style.selectedColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
int tick = 4;
|
|
||||||
|
|
||||||
int anchor_x, anchor_y, exit_x, exit_y;
|
|
||||||
|
|
||||||
if(p->x + p->w / 2 > p->cx) {
|
|
||||||
anchor_x = p->x;
|
|
||||||
} else {
|
|
||||||
anchor_x = p->x + p->w;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(p->y + p->h / 2 > p->cy) {
|
|
||||||
anchor_y = p->y - margin;
|
|
||||||
} else {
|
|
||||||
anchor_y = p->y + p->h + margin;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(abs(anchor_x - p->cx) > abs(anchor_y - p->cy)) {
|
|
||||||
exit_x = (anchor_x + p->cx) / 2;
|
|
||||||
exit_y = anchor_y;
|
|
||||||
} else {
|
|
||||||
exit_x = anchor_x;
|
|
||||||
exit_y = (anchor_y + p->cy) / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
Sint16 vx[3] = {
|
|
||||||
static_cast<Sint16>(p->cx),
|
|
||||||
static_cast<Sint16>(exit_x),
|
|
||||||
static_cast<Sint16>(anchor_x)};
|
|
||||||
|
|
||||||
Sint16 vy[3] = {
|
|
||||||
static_cast<Sint16>(p->cy),
|
|
||||||
static_cast<Sint16>(exit_y),
|
|
||||||
static_cast<Sint16>(anchor_y)};
|
|
||||||
|
|
||||||
boxRGBA(renderer, p->x, p->y, p->x + p->w, p->y + p->h, 0, 0, 0, 255);
|
|
||||||
|
|
||||||
bezierRGBA(renderer, vx, vy, 3, 2, drawColor.r, drawColor.g, drawColor.b, drawColor.a);
|
|
||||||
|
|
||||||
//lineRGBA(renderer, p->x,p->y - margin, p->x + tick, p->y - margin, drawColor.r, drawColor.g, drawColor.b, drawColor.a);
|
|
||||||
lineRGBA(renderer, p->x,p->y - margin, p->x + p->w, p->y - margin, drawColor.r, drawColor.g, drawColor.b, drawColor.a);
|
|
||||||
lineRGBA(renderer, p->x,p->y - margin, p->x, p->y - margin + tick, drawColor.r, drawColor.g, drawColor.b, drawColor.a);
|
|
||||||
|
|
||||||
// lineRGBA(renderer, p->x + p->w, p->y - margin, p->x + p->w - tick, p->y - margin, drawColor.r, drawColor.g, drawColor.b, drawColor.a);
|
|
||||||
lineRGBA(renderer, p->x + p->w, p->y - margin, p->x + p->w, p->y - margin + tick, drawColor.r, drawColor.g, drawColor.b, drawColor.a);
|
|
||||||
|
|
||||||
//lineRGBA(renderer, p->x, p->y + p->h + margin, p->x + tick, p->y + p->h + margin, drawColor.r, drawColor.g, drawColor.b, drawColor.a);
|
|
||||||
lineRGBA(renderer, p->x, p->y + p->h + margin, p->x + p->w, p->y + p->h + margin, drawColor.r, drawColor.g, drawColor.b, drawColor.a);
|
|
||||||
lineRGBA(renderer, p->x, p->y + p->h + margin, p->x, p->y + p->h + margin - tick, drawColor.r, drawColor.g, drawColor.b, drawColor.a);
|
|
||||||
|
|
||||||
// lineRGBA(renderer, p->x + p->w, p->y + p->h + margin,p->x + p->w - tick, p->y + p->h + margin, drawColor.r, drawColor.g, drawColor.b, drawColor.a);
|
|
||||||
lineRGBA(renderer, p->x + p->w, p->y + p->h + margin,p->x + p->w, p->y + p->h + margin - tick, drawColor.r, drawColor.g, drawColor.b, drawColor.a);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(p->labelLevel < 2 || p == selectedAircraft) {
|
|
||||||
// drawSignalMarks(p, p->x, p->y);
|
|
||||||
|
|
||||||
SDL_Color drawColor = style.labelColor;
|
|
||||||
drawColor.a = (int) (255.0f * p->opacity);
|
|
||||||
|
|
||||||
char flight[10] = "";
|
|
||||||
charCount = snprintf(flight,10," %s", p->flight);
|
|
||||||
|
|
||||||
if(charCount > 1) {
|
|
||||||
outRect = drawString(flight, p->x, p->y, mapBoldFont, drawColor);
|
|
||||||
|
|
||||||
totalWidth = std::max(totalWidth,outRect.w);
|
|
||||||
totalHeight += outRect.h;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(p->labelLevel < 1 || p == selectedAircraft) {
|
|
||||||
SDL_Color drawColor = style.subLabelColor;
|
|
||||||
drawColor.a = (int) (255.0f * p->opacity);
|
|
||||||
|
|
||||||
char alt[10] = "";
|
|
||||||
if (metric) {
|
|
||||||
charCount = snprintf(alt,10," %dm", (int) (p->altitude / 3.2828));
|
|
||||||
} else {
|
|
||||||
charCount = snprintf(alt,10," %d'", p->altitude);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(charCount > 1) {
|
|
||||||
// drawStringBG(alt, p->x, p->y + currentLine * mapFontHeight, mapFont, style.subLabelColor, style.labelBackground);
|
|
||||||
outRect = drawString(alt, p->x, p->y + totalHeight, mapFont, drawColor);
|
|
||||||
|
|
||||||
totalWidth = std::max(totalWidth,outRect.w);
|
|
||||||
totalHeight += outRect.h;
|
|
||||||
}
|
|
||||||
|
|
||||||
char speed[10] = "";
|
|
||||||
if (metric) {
|
|
||||||
charCount = snprintf(speed,10," %dkm/h", (int) (p->speed * 1.852));
|
|
||||||
} else {
|
|
||||||
charCount = snprintf(speed,10," %dmph", p->speed);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(charCount > 1) {
|
|
||||||
// drawStringBG(speed, p->x, p->y + currentLine * mapFontHeight, mapFont, style.subLabelColor, style.labelBackground);
|
|
||||||
outRect = drawString(speed, p->x, p->y + totalHeight, mapFont, drawColor);
|
|
||||||
|
|
||||||
totalWidth = std::max(totalWidth,outRect.w);
|
|
||||||
totalHeight += outRect.h;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//label debug
|
|
||||||
// char debug[25] = "";
|
|
||||||
// snprintf(debug,25,"%1.2f", p->labelLevel);
|
|
||||||
// drawString(debug, p->x, p->y + totalHeight, mapFont, style.red);
|
|
||||||
|
|
||||||
// if(maxCharCount > 1) {
|
|
||||||
|
|
||||||
// Sint16 vx[4] = {
|
|
||||||
// static_cast<Sint16>(p->cx),
|
|
||||||
// static_cast<Sint16>(p->cx + (p->x - p->cx) / 2),
|
|
||||||
// static_cast<Sint16>(p->x),
|
|
||||||
// static_cast<Sint16>(p->x)};
|
|
||||||
|
|
||||||
// Sint16 vy[4] = {
|
|
||||||
// static_cast<Sint16>(p->cy),
|
|
||||||
// static_cast<Sint16>(p->cy + (p->y - p->cy) / 2),
|
|
||||||
// static_cast<Sint16>(p->y - mapFontHeight),
|
|
||||||
// static_cast<Sint16>(p->y)};
|
|
||||||
|
|
||||||
// if(p->cy > p->y + currentLine * mapFontHeight) {
|
|
||||||
// vy[2] = p->y + currentLine * mapFontHeight + mapFontHeight;
|
|
||||||
// vy[3] = p->y + currentLine * mapFontHeight;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// bezierRGBA(renderer,vx,vy,4,2,style.labelLineColor.r,style.labelLineColor.g,style.labelLineColor.b,SDL_ALPHA_OPAQUE);
|
|
||||||
|
|
||||||
|
|
||||||
// lineRGBA(renderer,p->x,p->y,p->x,p->y+currentLine*mapFontHeight,style.labelLineColor.r,style.labelLineColor.g,style.labelLineColor.b,SDL_ALPHA_OPAQUE);
|
|
||||||
// }
|
|
||||||
|
|
||||||
p->target_w = totalWidth;
|
|
||||||
p->target_h = totalHeight;
|
|
||||||
|
|
||||||
p->w += 0.25f * (p->target_w - p->w);
|
|
||||||
p->h += 0.25f * (p->target_h - p->h);
|
|
||||||
|
|
||||||
if(p->w < 0.05f) {
|
|
||||||
p->w = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(p->h < 0.05f) {
|
|
||||||
p->h = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float View::resolveLabelConflicts() {
|
float View::resolveLabelConflicts() {
|
||||||
float label_force = 0.001f;
|
|
||||||
float label_dist = 2.0f;
|
|
||||||
float density_force = 0.05f;
|
|
||||||
float attachment_force = 0.0015f;
|
|
||||||
float attachment_dist = 10.0f;
|
|
||||||
float icon_force = 0.001f;
|
|
||||||
float icon_dist = 15.0f;
|
|
||||||
float boundary_force = 0.01f;
|
|
||||||
float damping_force = 0.85f;
|
|
||||||
float velocity_limit = 2.0f;
|
|
||||||
float edge_margin = 15.0f;
|
|
||||||
|
|
||||||
float maxV = 0.0f;
|
float maxV = 0.0f;
|
||||||
|
|
||||||
Aircraft *p = appData->aircraftList.head;
|
Aircraft *p = appData->aircraftList.head;
|
||||||
|
|
||||||
while(p) {
|
while(p) {
|
||||||
p->ddox = 0;
|
if(p->label) {
|
||||||
p->ddoy = 0;
|
p->label->clearAcceleration();
|
||||||
|
}
|
||||||
|
|
||||||
p = p->next;
|
p = p->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
p = appData->aircraftList.head;
|
p = appData->aircraftList.head;
|
||||||
|
|
||||||
while(p) {
|
while(p) {
|
||||||
//don't update on first run
|
if(p->label) {
|
||||||
if(p->x == 0) {
|
p->label->calculateForces(appData->aircraftList.head);
|
||||||
p = p->next;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Aircraft *check_p = appData->aircraftList.head;
|
|
||||||
|
|
||||||
int p_left = p->x;
|
|
||||||
int p_right = p->x + p->w;
|
|
||||||
int p_top = p->y;
|
|
||||||
int p_bottom = p->y + p->h;
|
|
||||||
|
|
||||||
|
|
||||||
float boxmid_x = (float)(p_left + p_right) / 2.0f;
|
|
||||||
float boxmid_y = (float)(p_top + p_bottom) / 2.0f;
|
|
||||||
|
|
||||||
float offset_x = boxmid_x - p->cx;
|
|
||||||
float offset_y = boxmid_y - p->cy;
|
|
||||||
|
|
||||||
float target_length_x = attachment_dist + p->w / 2.0f;
|
|
||||||
float target_length_y = attachment_dist + p->h / 2.0f;
|
|
||||||
|
|
||||||
// stay icon_dist away from own icon
|
|
||||||
|
|
||||||
p->ddox -= sign(offset_x) * attachment_force * (fabs(offset_x) - target_length_x);
|
|
||||||
p->ddoy -= sign(offset_y) * attachment_force * (fabs(offset_y) - target_length_y);
|
|
||||||
|
|
||||||
|
|
||||||
// // //screen edge
|
|
||||||
|
|
||||||
if(p_left < edge_margin) {
|
|
||||||
p->ddox += boundary_force * (float)(edge_margin - p_left);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(p_right > screen_width - edge_margin) {
|
|
||||||
p->ddox += boundary_force * (float)(screen_width - edge_margin - p_right);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(p_top < edge_margin) {
|
|
||||||
p->ddoy += boundary_force * (float)(edge_margin - p_top);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(p_bottom > screen_height - edge_margin) {
|
|
||||||
p->ddoy += boundary_force * (float)(screen_height - edge_margin - p_bottom);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
float all_x = 0;
|
|
||||||
float all_y = 0;
|
|
||||||
int count = 0;
|
|
||||||
//check against other labels
|
|
||||||
|
|
||||||
float density_max = 0;
|
|
||||||
|
|
||||||
while(check_p) {
|
|
||||||
if(check_p->addr == p->addr) {
|
|
||||||
check_p = check_p -> next;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//calculate density for label display level (inversely proportional to area of smallest box connecting this to neighbor)
|
|
||||||
float density = 1.0 / (0.001f + fabs(p->x - check_p->x) * fabs (p->x - check_p->y));
|
|
||||||
|
|
||||||
if(density > density_max) {
|
|
||||||
density_max = density;
|
|
||||||
}
|
|
||||||
|
|
||||||
density = 1.0 / (0.001f + fabs(p->x - check_p->cx) * fabs(p->x - check_p->cy));
|
|
||||||
|
|
||||||
if(density > density_max) {
|
|
||||||
density_max = density;
|
|
||||||
}
|
|
||||||
|
|
||||||
int check_left = check_p->x;
|
|
||||||
int check_right = check_p->x + check_p->w;
|
|
||||||
int check_top = check_p->y;
|
|
||||||
int check_bottom = check_p->y + check_p->h;
|
|
||||||
|
|
||||||
float icon_x = (float)check_p->cx;
|
|
||||||
float icon_y = (float)check_p->cy;
|
|
||||||
|
|
||||||
float checkboxmid_x = (float)(check_left + check_right) / 2.0f;
|
|
||||||
float checkboxmid_y = (float)(check_top + check_bottom) / 2.0f;
|
|
||||||
|
|
||||||
float offset_x = boxmid_x - checkboxmid_x;
|
|
||||||
float offset_y = boxmid_y - checkboxmid_y;
|
|
||||||
|
|
||||||
float target_length_x = label_dist + (float)(check_p->w + p->w) / 2.0f;
|
|
||||||
float target_length_y = label_dist + (float)(check_p->h + p->h) / 2.0f;
|
|
||||||
|
|
||||||
float x_mag = std::max(0.0f,(target_length_x - fabs(offset_x)));
|
|
||||||
float y_mag = std::max(0.0f,(target_length_y - fabs(offset_y)));
|
|
||||||
|
|
||||||
// stay at least label_dist away from other icons
|
|
||||||
|
|
||||||
if(x_mag > 0 && y_mag > 0) {
|
|
||||||
p->ddox += sign(offset_x) * label_force * x_mag;
|
|
||||||
p->ddoy += sign(offset_y) * label_force * y_mag;
|
|
||||||
}
|
|
||||||
|
|
||||||
// stay at least icon_dist away from other icons
|
|
||||||
|
|
||||||
offset_x = boxmid_x - check_p->cx;
|
|
||||||
offset_y = boxmid_y - check_p->cy;
|
|
||||||
|
|
||||||
target_length_x = icon_dist + (float)check_p->w / 2.0f;
|
|
||||||
target_length_y = icon_dist + (float)check_p->h / 2.0f;
|
|
||||||
|
|
||||||
x_mag = std::max(0.0f,(target_length_x - fabs(offset_x)));
|
|
||||||
y_mag = std::max(0.0f,(target_length_y - fabs(offset_y)));
|
|
||||||
|
|
||||||
if(x_mag > 0 && y_mag > 0) {
|
|
||||||
p->ddox += sign(offset_x) * icon_force * x_mag;
|
|
||||||
p->ddoy += sign(offset_y) * icon_force * y_mag;
|
|
||||||
}
|
|
||||||
|
|
||||||
all_x += sign(boxmid_x - checkboxmid_x);
|
|
||||||
all_y += sign(boxmid_y - checkboxmid_y);
|
|
||||||
|
|
||||||
count++;
|
|
||||||
|
|
||||||
check_p = check_p -> next;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// move away from others
|
|
||||||
p->ddox += density_force * all_x / count;
|
|
||||||
p->ddoy += density_force * all_y / count;
|
|
||||||
|
|
||||||
// label drawlevel hysteresis
|
|
||||||
|
|
||||||
float density_mult = 100.0f;
|
|
||||||
float level_rate = 0.0005f;
|
|
||||||
|
|
||||||
if(p->labelLevel < -1.25f + density_mult * density_max) {
|
|
||||||
p->labelLevel += level_rate;
|
|
||||||
} else if (p->labelLevel > 0.5f + density_mult * density_max) {
|
|
||||||
p->labelLevel -= level_rate;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
p = p->next;
|
p = p->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
//update
|
|
||||||
|
|
||||||
p = appData->aircraftList.head;
|
p = appData->aircraftList.head;
|
||||||
|
|
||||||
while(p) {
|
while(p) {
|
||||||
|
|
||||||
// if this is the first update don't update based on physics
|
if(p->label) {
|
||||||
if(p->x == 0) {
|
p->label->applyForces();
|
||||||
p->x = p->cx;
|
|
||||||
p->y = p->cy + 20*screen_uiscale;
|
|
||||||
|
|
||||||
p = p->next;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//add noise to acceleration to help with resonance and stuck labels
|
|
||||||
// float noise_x = ((float) rand() / (float) RAND_MAX) - 0.5f;
|
|
||||||
// float noise_y = ((float) rand() / (float) RAND_MAX) - 0.5f;
|
|
||||||
|
|
||||||
|
|
||||||
p->dox += p->ddox;// + 0.001f;// * noise_x;
|
|
||||||
p->doy += p->ddoy;// + 0.001f;//. * noise_y;
|
|
||||||
|
|
||||||
p->dox *= damping_force;
|
|
||||||
p->doy *= damping_force;
|
|
||||||
|
|
||||||
if(fabs(p->dox) > velocity_limit) {
|
|
||||||
p->dox = sign(p->dox) * velocity_limit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(fabs(p->doy) > velocity_limit) {
|
|
||||||
p->doy = sign(p->doy) * velocity_limit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(fabs(p->dox) < 0.01f) {
|
|
||||||
p->dox = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(fabs(p->doy) < 0.01f) {
|
|
||||||
p->doy = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
p->ox += p->dox;
|
|
||||||
p->oy += p->doy;
|
|
||||||
|
|
||||||
p->x = p->cx + (int)round(p->ox);
|
|
||||||
p->y = p->cy + (int)round(p->oy);
|
|
||||||
|
|
||||||
|
|
||||||
if(fabs(p->dox) > maxV) {
|
|
||||||
maxV = fabs(p->dox);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(fabs(p->doy) > maxV) {
|
|
||||||
maxV = fabs(p->doy);
|
|
||||||
}
|
|
||||||
|
|
||||||
//debug box
|
|
||||||
// rectangleRGBA(renderer, p->x, p->y, p->x + p->w, p->y + p->h, 255,0,0, SDL_ALPHA_OPAQUE);
|
|
||||||
// lineRGBA(renderer, p->cx, p->cy, p->x, p->y, 0,255,0, SDL_ALPHA_OPAQUE);
|
|
||||||
// lineRGBA(renderer,p->x, p->y, p->x + p->ddox, p->y+p->ddoy, 255,0,255,255);
|
|
||||||
// lineRGBA(renderer,p->x, p->y, p->x + p->dox, p->y+p->doy, 0,255,255,255);
|
|
||||||
|
|
||||||
p = p->next;
|
p = p->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1372,7 +945,7 @@ void View::drawPlanes() {
|
||||||
// float predx = x + float(elapsed(p->msSeenLatLon)) * velx;
|
// float predx = x + float(elapsed(p->msSeenLatLon)) * velx;
|
||||||
// float predy = y + float(elapsed(p->msSeenLatLon)) * vely;
|
// float predy = y + float(elapsed(p->msSeenLatLon)) * vely;
|
||||||
// circleRGBA(renderer, predx, predy, 4 * screen_uiscale, 127,127, 127, 255);
|
// circleRGBA(renderer, predx, predy, 4 * screen_uiscale, 127,127, 127, 255);
|
||||||
// lineRGBA(renderer, p->cx, p->cy, predx, predy, 127,127, 127, 255);
|
// lineRGBA(renderer, p->x, p->y, predx, predy, 127,127, 127, 255);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
planeColor = lerpColor(style.planeColor, style.planeGoneColor, float(elapsed_s(p->msSeen)) / (float) DISPLAY_ACTIVE);
|
planeColor = lerpColor(style.planeColor, style.planeGoneColor, float(elapsed_s(p->msSeen)) / (float) DISPLAY_ACTIVE);
|
||||||
|
@ -1382,18 +955,18 @@ void View::drawPlanes() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(outOfBounds(x,y)) {
|
if(outOfBounds(x,y)) {
|
||||||
drawPlaneOffMap(x, y, &(p->cx), &(p->cy), planeColor);
|
drawPlaneOffMap(x, y, &(p->x), &(p->y), planeColor);
|
||||||
} else {
|
} else {
|
||||||
drawPlaneIcon(usex, usey, p->track, planeColor);
|
drawPlaneIcon(usex, usey, p->track, planeColor);
|
||||||
|
|
||||||
p->cx = usex;
|
p->x = usex;
|
||||||
p->cy = usey;
|
p->y = usey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//show latlon ping
|
//show latlon ping
|
||||||
if(elapsed(p->msSeenLatLon) < 500) {
|
if(elapsed(p->msSeenLatLon) < 500) {
|
||||||
circleRGBA(renderer, p->cx, p->cy, elapsed(p->msSeenLatLon) * screen_width / (8192), 127,127, 127, 255 - (uint8_t)(255.0 * elapsed(p->msSeenLatLon) / 500.0));
|
circleRGBA(renderer, p->x, p->y, elapsed(p->msSeenLatLon) * screen_width / (8192), 127,127, 127, 255 - (uint8_t)(255.0 * elapsed(p->msSeenLatLon) / 500.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
drawPlaneText(p);
|
drawPlaneText(p);
|
||||||
|
@ -1541,18 +1114,18 @@ void View::drawClick() {
|
||||||
} else {
|
} else {
|
||||||
boxSize = 20;
|
boxSize = 20;
|
||||||
}
|
}
|
||||||
//rectangleRGBA(renderer, selectedAircraft->cx - boxSize, selectedAircraft->cy - boxSize, selectedAircraft->cx + boxSize, selectedAircraft->cy + boxSize, style.selectedColor.r, style.selectedColor.g, style.selectedColor.b, 255);
|
//rectangleRGBA(renderer, selectedAircraft->x - boxSize, selectedAircraft->y - boxSize, selectedAircraft->x + boxSize, selectedAircraft->y + boxSize, style.selectedColor.r, style.selectedColor.g, style.selectedColor.b, 255);
|
||||||
lineRGBA(renderer, selectedAircraft->cx - boxSize, selectedAircraft->cy - boxSize, selectedAircraft->cx - boxSize/2, selectedAircraft->cy - boxSize, style.selectedColor.r, style.selectedColor.g, style.selectedColor.b, 255);
|
lineRGBA(renderer, selectedAircraft->x - boxSize, selectedAircraft->y - boxSize, selectedAircraft->x - boxSize/2, selectedAircraft->y - boxSize, style.selectedColor.r, style.selectedColor.g, style.selectedColor.b, 255);
|
||||||
lineRGBA(renderer, selectedAircraft->cx - boxSize, selectedAircraft->cy - boxSize, selectedAircraft->cx - boxSize, selectedAircraft->cy - boxSize/2, style.selectedColor.r, style.selectedColor.g, style.selectedColor.b, 255);
|
lineRGBA(renderer, selectedAircraft->x - boxSize, selectedAircraft->y - boxSize, selectedAircraft->x - boxSize, selectedAircraft->y - boxSize/2, style.selectedColor.r, style.selectedColor.g, style.selectedColor.b, 255);
|
||||||
|
|
||||||
lineRGBA(renderer, selectedAircraft->cx + boxSize, selectedAircraft->cy - boxSize, selectedAircraft->cx + boxSize/2, selectedAircraft->cy - boxSize, style.selectedColor.r, style.selectedColor.g, style.selectedColor.b, 255);
|
lineRGBA(renderer, selectedAircraft->x + boxSize, selectedAircraft->y - boxSize, selectedAircraft->x + boxSize/2, selectedAircraft->y - boxSize, style.selectedColor.r, style.selectedColor.g, style.selectedColor.b, 255);
|
||||||
lineRGBA(renderer, selectedAircraft->cx + boxSize, selectedAircraft->cy - boxSize, selectedAircraft->cx + boxSize, selectedAircraft->cy - boxSize/2, style.selectedColor.r, style.selectedColor.g, style.selectedColor.b, 255);
|
lineRGBA(renderer, selectedAircraft->x + boxSize, selectedAircraft->y - boxSize, selectedAircraft->x + boxSize, selectedAircraft->y - boxSize/2, style.selectedColor.r, style.selectedColor.g, style.selectedColor.b, 255);
|
||||||
|
|
||||||
lineRGBA(renderer, selectedAircraft->cx + boxSize, selectedAircraft->cy + boxSize, selectedAircraft->cx + boxSize/2, selectedAircraft->cy + boxSize, style.selectedColor.r, style.selectedColor.g, style.selectedColor.b, 255);
|
lineRGBA(renderer, selectedAircraft->x + boxSize, selectedAircraft->y + boxSize, selectedAircraft->x + boxSize/2, selectedAircraft->y + boxSize, style.selectedColor.r, style.selectedColor.g, style.selectedColor.b, 255);
|
||||||
lineRGBA(renderer, selectedAircraft->cx + boxSize, selectedAircraft->cy + boxSize, selectedAircraft->cx + boxSize, selectedAircraft->cy + boxSize/2, style.selectedColor.r, style.selectedColor.g, style.selectedColor.b, 255);
|
lineRGBA(renderer, selectedAircraft->x + boxSize, selectedAircraft->y + boxSize, selectedAircraft->x + boxSize, selectedAircraft->y + boxSize/2, style.selectedColor.r, style.selectedColor.g, style.selectedColor.b, 255);
|
||||||
|
|
||||||
lineRGBA(renderer, selectedAircraft->cx - boxSize, selectedAircraft->cy + boxSize, selectedAircraft->cx - boxSize/2, selectedAircraft->cy + boxSize, style.selectedColor.r, style.selectedColor.g, style.selectedColor.b, 255);
|
lineRGBA(renderer, selectedAircraft->x - boxSize, selectedAircraft->y + boxSize, selectedAircraft->x - boxSize/2, selectedAircraft->y + boxSize, style.selectedColor.r, style.selectedColor.g, style.selectedColor.b, 255);
|
||||||
lineRGBA(renderer, selectedAircraft->cx - boxSize, selectedAircraft->cy + boxSize, selectedAircraft->cx - boxSize, selectedAircraft->cy + boxSize/2, style.selectedColor.r, style.selectedColor.g, style.selectedColor.b, 255);
|
lineRGBA(renderer, selectedAircraft->x - boxSize, selectedAircraft->y + boxSize, selectedAircraft->x - boxSize, selectedAircraft->y + boxSize/2, style.selectedColor.r, style.selectedColor.g, style.selectedColor.b, 255);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1563,10 +1136,10 @@ void View::registerClick(int tapcount, int x, int y) {
|
||||||
|
|
||||||
while(p) {
|
while(p) {
|
||||||
if(x && y) {
|
if(x && y) {
|
||||||
if((p->cx - x) * (p->cx - x) + (p->cy - y) * (p->cy - y) < 900) {
|
if((p->x - x) * (p->x - x) + (p->y - y) * (p->y - y) < 900) {
|
||||||
if(selection) {
|
if(selection) {
|
||||||
if((p->cx - x) * (p->cx - x) + (p->cy - y) * (p->cy - y) <
|
if((p->x - x) * (p->x - x) + (p->y - y) * (p->y - y) <
|
||||||
(selection->cx - x) * (selection->cx - x) + (selection->cy - y) * (selection->cy - y)) {
|
(selection->x - x) * (selection->x - x) + (selection->y - y) * (selection->y - y)) {
|
||||||
selection = p;
|
selection = p;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1615,9 +1188,10 @@ void View::draw() {
|
||||||
drawGeography();
|
drawGeography();
|
||||||
|
|
||||||
for(int i = 0; i < 8; i++) {
|
for(int i = 0; i < 8; i++) {
|
||||||
if(resolveLabelConflicts() < 0.001f) {
|
// if(resolveLabelConflicts() < 0.001f) {
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
|
resolveLabelConflicts();
|
||||||
}
|
}
|
||||||
|
|
||||||
lineCount = 0;
|
lineCount = 0;
|
||||||
|
@ -1631,7 +1205,9 @@ void View::draw() {
|
||||||
if(fps) {
|
if(fps) {
|
||||||
char fps[60] = " ";
|
char fps[60] = " ";
|
||||||
snprintf(fps,40," %d lines @ %.1ffps", lineCount, 1000.0 / elapsed(lastFrameTime));
|
snprintf(fps,40," %d lines @ %.1ffps", lineCount, 1000.0 / elapsed(lastFrameTime));
|
||||||
drawStringBG(fps, 0,0, mapFont, style.subLabelColor, style.backgroundColor);
|
|
||||||
|
|
||||||
|
//drawStringBG(fps, 0,0, mapFont, style.subLabelColor, style.backgroundColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_RenderPresent(renderer);
|
SDL_RenderPresent(renderer);
|
||||||
|
|
92
View.h
92
View.h
|
@ -34,11 +34,13 @@
|
||||||
|
|
||||||
#include "AppData.h"
|
#include "AppData.h"
|
||||||
#include "Map.h"
|
#include "Map.h"
|
||||||
|
#include "Style.h"
|
||||||
#include "SDL2/SDL.h"
|
#include "SDL2/SDL.h"
|
||||||
#include "SDL2/SDL_ttf.h"
|
#include "SDL2/SDL_ttf.h"
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
//defs - should all move to config file setup
|
//defs - should all move to config file setup
|
||||||
#define ROUND_RADIUS 3 //radius of text box corners
|
#define ROUND_RADIUS 3 //radius of text box corners
|
||||||
|
|
||||||
|
@ -58,96 +60,6 @@
|
||||||
#define LATLONMULT 111.195 // 6371.0 * M_PI / 180.0
|
#define LATLONMULT 111.195 // 6371.0 * M_PI / 180.0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// This should go to a full theming class
|
|
||||||
//
|
|
||||||
typedef struct Style {
|
|
||||||
SDL_Color backgroundColor;
|
|
||||||
|
|
||||||
SDL_Color selectedColor;
|
|
||||||
SDL_Color planeColor;
|
|
||||||
SDL_Color planeGoneColor;
|
|
||||||
SDL_Color trailColor;
|
|
||||||
|
|
||||||
SDL_Color geoColor;
|
|
||||||
SDL_Color airportColor;
|
|
||||||
|
|
||||||
SDL_Color labelColor;
|
|
||||||
SDL_Color labelLineColor;
|
|
||||||
SDL_Color subLabelColor;
|
|
||||||
SDL_Color labelBackground;
|
|
||||||
|
|
||||||
SDL_Color scaleBarColor;
|
|
||||||
SDL_Color buttonColor;
|
|
||||||
SDL_Color buttonBackground;
|
|
||||||
SDL_Color buttonOutline;
|
|
||||||
|
|
||||||
SDL_Color clickColor;
|
|
||||||
|
|
||||||
SDL_Color black;
|
|
||||||
SDL_Color white;
|
|
||||||
SDL_Color red;
|
|
||||||
SDL_Color green;
|
|
||||||
SDL_Color blue;
|
|
||||||
|
|
||||||
//
|
|
||||||
// todo separate style stuff
|
|
||||||
//
|
|
||||||
|
|
||||||
Style() {
|
|
||||||
|
|
||||||
SDL_Color pink = {249,38,114,255};
|
|
||||||
|
|
||||||
SDL_Color purple = {85, 0, 255,255};
|
|
||||||
SDL_Color purple_dark = {33, 0, 122,255};
|
|
||||||
|
|
||||||
SDL_Color blue = {102,217,239,255};
|
|
||||||
SDL_Color blue_dark = {102,217,239,255};
|
|
||||||
|
|
||||||
SDL_Color green = {0,255,234,255};
|
|
||||||
SDL_Color green_dark = {24,100,110,255};
|
|
||||||
|
|
||||||
SDL_Color yellow = {216,255,0,255};
|
|
||||||
SDL_Color yellow_dark = {90,133,50,255};
|
|
||||||
|
|
||||||
SDL_Color orange = {253,151,31,255};
|
|
||||||
SDL_Color grey_light = {196,196,196,255};
|
|
||||||
SDL_Color grey = {127,127,127,255};
|
|
||||||
SDL_Color grey_dark = {64,64,64,255};
|
|
||||||
black = {0,0,0,255};
|
|
||||||
white = {255,255,255,255};
|
|
||||||
red = {255,0,0,255};
|
|
||||||
green = {0,255,0,255};
|
|
||||||
blue = {0,0,255,255};
|
|
||||||
|
|
||||||
|
|
||||||
backgroundColor = black;
|
|
||||||
|
|
||||||
selectedColor = pink;
|
|
||||||
planeColor = yellow;
|
|
||||||
planeGoneColor = grey;
|
|
||||||
trailColor = yellow_dark;
|
|
||||||
|
|
||||||
geoColor = purple_dark;
|
|
||||||
airportColor = purple;
|
|
||||||
|
|
||||||
labelColor = white;
|
|
||||||
labelLineColor = grey_dark;
|
|
||||||
subLabelColor = grey;
|
|
||||||
labelBackground = black;
|
|
||||||
scaleBarColor = grey_light;
|
|
||||||
buttonColor = grey_light;
|
|
||||||
buttonBackground = black;
|
|
||||||
buttonOutline = grey_light;
|
|
||||||
|
|
||||||
clickColor = grey;
|
|
||||||
}
|
|
||||||
} Style;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class View {
|
class View {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Reference in a new issue