mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-10 04:57:00 -04:00
Switch (back) to our own Color type instead of using wxColour.
The reason is that wxColour's default constructor creates an invalid color (what is that even?). It is nicer to just have default be transparent.
This commit is contained in:
@@ -41,7 +41,12 @@ IMPLEMENT_REFLECTION(ColorField) {
|
||||
IMPLEMENT_REFLECTION(ColorField::Choice) {
|
||||
REFLECT_IF_READING_SINGLE_VALUE {
|
||||
REFLECT_NAMELESS(name);
|
||||
color = parse_color(name);
|
||||
auto col = parse_color(name);
|
||||
if (col) {
|
||||
color = *col;
|
||||
} else {
|
||||
// TODO: handler.warning(_("Not a valid color value: ") + name);
|
||||
}
|
||||
} else {
|
||||
REFLECT(name);
|
||||
REFLECT(color);
|
||||
@@ -78,7 +83,7 @@ ColorValue::ColorValue(const ColorFieldP& field)
|
||||
: Value(field)
|
||||
, value( !field->initial.isDefault() ? field->initial()
|
||||
: !field->choices.empty() ? field->choices[0]->color
|
||||
: *wxBLACK
|
||||
: Color()
|
||||
, true)
|
||||
{}
|
||||
|
||||
|
||||
+28
-18
@@ -11,11 +11,14 @@
|
||||
|
||||
// ----------------------------------------------------------------------------- : Parsing etc.
|
||||
|
||||
template <> void Reader::handle(Color& col) {
|
||||
col = parse_color(getValue());
|
||||
if (!col.Ok()) {
|
||||
col = Color(0,0,0,0);
|
||||
warning(_("Not a valid color value"));
|
||||
template <> void Reader::handle(Color& out) {
|
||||
String const& str = getValue();
|
||||
auto col = parse_color(str);
|
||||
if (!col.has_value()) {
|
||||
out = Color();
|
||||
warning(_("Not a valid color value: ") + str);
|
||||
} else {
|
||||
out = *col;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +27,7 @@ template <> void Writer::handle(const Color& col) {
|
||||
}
|
||||
|
||||
|
||||
Color parse_color(const String& v) {
|
||||
optional<Color> parse_color(const String& v) {
|
||||
UInt r,g,b,a;
|
||||
if (wxSscanf(v.c_str(),_("rgb(%u,%u,%u)"),&r,&g,&b)) {
|
||||
return Color(r, g, b);
|
||||
@@ -33,7 +36,13 @@ Color parse_color(const String& v) {
|
||||
} else if (v == _("transparent")) {
|
||||
return Color(0,0,0,0);
|
||||
} else {
|
||||
return Color(v);
|
||||
// Try to find a named color
|
||||
wxColour c = wxTheColourDatabase->Find(v);
|
||||
if (c.Ok()) {
|
||||
return Color(c);
|
||||
} else {
|
||||
return optional<Color>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +58,7 @@ String format_color(Color col) {
|
||||
|
||||
// ----------------------------------------------------------------------------- : Color utility functions
|
||||
|
||||
Color lerp(const Color& a, const Color& b, double t) {
|
||||
Color lerp(Color a, Color b, double t) {
|
||||
return Color(static_cast<int>( a.Red() + (b.Red() - a.Red() ) * t ),
|
||||
static_cast<int>( a.Green() + (b.Green() - a.Green()) * t ),
|
||||
static_cast<int>( a.Blue() + (b.Blue() - a.Blue() ) * t ),
|
||||
@@ -79,21 +88,22 @@ Color hsl2rgb(double h, double s, double l) {
|
||||
}
|
||||
|
||||
|
||||
Color darken(const Color& c) {
|
||||
Color darken(Color c) {
|
||||
return Color(
|
||||
c.Red() * 8 / 10,
|
||||
c.Green() * 8 / 10,
|
||||
c.Blue() * 8 / 10
|
||||
c.r * 8 / 10,
|
||||
c.g * 8 / 10,
|
||||
c.b * 8 / 10,
|
||||
c.a
|
||||
);
|
||||
}
|
||||
|
||||
Color saturate(const Color& c, double amount) {
|
||||
int r = c.Red(), g = c.Green(), b = c.Blue();
|
||||
double l = (r + g + b) / 3;
|
||||
Color saturate(Color c, double amount) {
|
||||
double l = (c.r + c.g + c.b) / 3;
|
||||
return Color(
|
||||
col(static_cast<int>( (r - amount * l) / (1 - amount) )),
|
||||
col(static_cast<int>( (g - amount * l) / (1 - amount) )),
|
||||
col(static_cast<int>( (b - amount * l) / (1 - amount) ))
|
||||
col(static_cast<int>( (c.r - amount * l) / (1 - amount) )),
|
||||
col(static_cast<int>( (c.g - amount * l) / (1 - amount) )),
|
||||
col(static_cast<int>( (c.b - amount * l) / (1 - amount) )),
|
||||
c.a
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+42
-5
@@ -14,9 +14,45 @@
|
||||
// ----------------------------------------------------------------------------- : Includes
|
||||
|
||||
#include <util/prec.hpp>
|
||||
#include <optional>
|
||||
|
||||
// ----------------------------------------------------------------------------- : Colors
|
||||
|
||||
// Colors.
|
||||
// Ideally we would just use wxColour, but that class is stupid because it has an "invalid" state,
|
||||
// and the default constructor makes invalid values.
|
||||
struct Color {
|
||||
union {
|
||||
struct {
|
||||
unsigned char r, g, b, a;
|
||||
};
|
||||
uint32_t packed;
|
||||
};
|
||||
|
||||
inline Color() : r(0), g(0), b(0), a(0) {}
|
||||
inline Color(unsigned char r, unsigned char g, unsigned char b, unsigned char a = 255) : r(r), g(g), b(b), a(a) {}
|
||||
inline Color(wxColour color) : r(color.Red()), g(color.Green()), b(color.Blue()), a(color.Alpha()) {}
|
||||
|
||||
inline operator wxColour() const { return wxColour(r, g, b, a); }
|
||||
inline operator wxPen() const { return wxPen((wxColour)*this); }
|
||||
inline operator wxBrush() const { return wxBrush((wxColour)*this); }
|
||||
|
||||
inline bool operator == (Color const& that) const {
|
||||
return packed == that.packed;
|
||||
}
|
||||
inline bool operator != (Color const& that) const {
|
||||
return packed != that.packed;
|
||||
}
|
||||
|
||||
inline constexpr unsigned char Red() const { return r; }
|
||||
inline constexpr unsigned char Green() const { return g; }
|
||||
inline constexpr unsigned char Blue() const { return b; }
|
||||
inline constexpr unsigned char Alpha() const { return a; }
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// RGB Color, packed into 3 bytes
|
||||
// These are used for arrays in wxImage
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// stupid headers stealing useful names
|
||||
@@ -37,6 +73,7 @@ struct RGB {
|
||||
RGB() {}
|
||||
RGB(Byte x) : r(x), g(x), b(x) {}
|
||||
RGB(Byte r, Byte g, Byte b) : r(r), g(g), b(b) {}
|
||||
RGB(Color x) : r(x.Red()), g(x.Green()), b(x.Blue()) {}
|
||||
RGB(wxColour const& x) : r(x.Red()), g(x.Green()), b(x.Blue()) {}
|
||||
|
||||
inline int total() { return r+g+b; }
|
||||
@@ -65,7 +102,7 @@ struct RGB {
|
||||
// ----------------------------------------------------------------------------- : Parsing
|
||||
|
||||
/// Parse a color
|
||||
Color parse_color(const String& value);
|
||||
optional<Color> parse_color(const String& value);
|
||||
|
||||
/// Convert a Color to a string
|
||||
String format_color(Color col);
|
||||
@@ -77,19 +114,19 @@ inline int top(int x) { return min(255, x); } ///< top range check for color
|
||||
inline int col(int x) { return top(bot(x)); } ///< top and bottom range check for color values
|
||||
|
||||
/// Linear interpolation between colors
|
||||
Color lerp(const Color& a, const Color& b, double t);
|
||||
Color lerp(Color a, Color b, double t);
|
||||
|
||||
/// convert HSL to RGB, h,s,l must be in range [0...1)
|
||||
Color hsl2rgb(double h, double s, double l);
|
||||
|
||||
/// A darker version of a color
|
||||
Color darken(const Color& c);
|
||||
Color darken(Color c);
|
||||
|
||||
/// A black or white color, that contrasts with c
|
||||
Color contrasting_color(const Color& c);
|
||||
Color contrasting_color(Color c);
|
||||
|
||||
/// A saturated version of a color
|
||||
Color saturate(const Color& c, double amount);
|
||||
Color saturate(Color c, double amount);
|
||||
|
||||
/// Recolor:
|
||||
/**
|
||||
|
||||
@@ -40,7 +40,7 @@ void AboutWindow::draw(DC& dc) {
|
||||
wxSize ws = GetClientSize();
|
||||
// draw background
|
||||
dc.SetPen (*wxTRANSPARENT_PEN);
|
||||
dc.SetBrush(Color(240,247,255));
|
||||
dc.SetBrush(wxColor(240,247,255));
|
||||
dc.DrawRectangle(0, 0, ws.GetWidth(), ws.GetHeight());
|
||||
// draw logo
|
||||
dc.DrawBitmap(logo, (ws.GetWidth() - logo.GetWidth()) / 2, 5);
|
||||
@@ -48,11 +48,11 @@ void AboutWindow::draw(DC& dc) {
|
||||
dc.DrawBitmap(logo2, ws.GetWidth() - logo2.GetWidth(), ws.GetHeight() - logo2.GetHeight());
|
||||
#endif
|
||||
// draw version box
|
||||
dc.SetPen (wxPen(Color(184,29,19), 2));
|
||||
dc.SetBrush(Color(114,197,224));
|
||||
dc.SetPen (wxPen(wxColor(184,29,19), 2));
|
||||
dc.SetBrush(wxColor(114,197,224));
|
||||
dc.DrawRectangle(28, 104, 245, 133);
|
||||
dc.SetTextBackground(Color(114,197,224));
|
||||
dc.SetTextForeground(Color(0,0,0));
|
||||
dc.SetTextBackground(wxColor(114,197,224));
|
||||
dc.SetTextForeground(wxColor(0,0,0));
|
||||
// draw version info
|
||||
dc.SetFont(wxFont(9, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, _("Arial")));
|
||||
dc.DrawText(_("Version: ") + app_version.toString() + version_suffix, 34, 110);
|
||||
@@ -202,7 +202,7 @@ void HoverButton::draw(DC& dc) {
|
||||
// clear background (for transparent button images)
|
||||
wxSize ws = GetClientSize();
|
||||
dc.SetPen(*wxTRANSPARENT_PEN);
|
||||
dc.SetBrush(background != wxNullColour ? background : wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
|
||||
dc.SetBrush(wxBrush(background.Alpha()>0 ? wxColour(background) : wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE)));
|
||||
dc.DrawRectangle(0, 0, ws.GetWidth(), ws.GetHeight());
|
||||
// draw button
|
||||
dc.DrawBitmap(*toDraw(), 0, 0, true);
|
||||
|
||||
@@ -310,7 +310,7 @@ void GalleryList::OnDraw(DC& dc) {
|
||||
}
|
||||
#else
|
||||
Color c = selected ? ( focused
|
||||
? wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT)
|
||||
? Color(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT))
|
||||
: lerp(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW),
|
||||
wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT), subcolumnActivity(j))
|
||||
)
|
||||
|
||||
@@ -44,7 +44,7 @@ CardsPanel::CardsPanel(Window* parent, int id)
|
||||
card_list = new FilteredImageCardList(splitter, ID_CARD_LIST);
|
||||
nodes_panel = new wxPanel(splitter, wxID_ANY);
|
||||
notes = new TextCtrl(nodes_panel, ID_NOTES, true);
|
||||
collapse_notes = new HoverButton(nodes_panel, ID_COLLAPSE_NOTES, _("btn_collapse"), wxNullColour, false);
|
||||
collapse_notes = new HoverButton(nodes_panel, ID_COLLAPSE_NOTES, _("btn_collapse"), Color(), false);
|
||||
collapse_notes->SetExtraStyle(wxWS_EX_PROCESS_UI_UPDATES);
|
||||
filter = nullptr;
|
||||
editor->next_in_tab_order = card_list;
|
||||
|
||||
@@ -260,7 +260,7 @@ void StatDimensionList::drawItem(DC& dc, int x, int y, size_t item) {
|
||||
int cx = x + subcolumns[j].offset.x + subcolumns[j].size.x/2;
|
||||
int cy = y + subcolumns[j].offset.y + subcolumns[j].size.y/2;
|
||||
dc.SetPen(*wxTRANSPARENT_PEN);
|
||||
dc.SetBrush(prefered ? wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)
|
||||
dc.SetBrush(prefered ? Color(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT))
|
||||
: lerp(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT),wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW),0.5));
|
||||
dc.DrawCircle(cx,cy,6);
|
||||
}
|
||||
|
||||
@@ -151,6 +151,6 @@ void ColorValueEditor::change(const Defaultable<Color>& c) {
|
||||
addAction(value_action(valueP(), c));
|
||||
}
|
||||
void ColorValueEditor::changeCustom() {
|
||||
Color c = wxGetColourFromUser(0, value().value());
|
||||
if (c.Ok()) change(c);
|
||||
wxColour c = wxGetColourFromUser(0, value().value());
|
||||
if (c.Ok()) change(Color(c));
|
||||
}
|
||||
|
||||
@@ -127,9 +127,13 @@ struct TextElementsFromString {
|
||||
else if (is_substr(text, tag_start, _( "<color"))) {
|
||||
size_t colon = text.find_first_of(_(">:"), tag_start);
|
||||
if (colon < pos - 1 && text.GetChar(colon) == _(':')) {
|
||||
Color c = parse_color(text.substr(colon+1, pos-colon-2));
|
||||
if (!c.Ok()) c = style.font.color;
|
||||
colors.push_back(c);
|
||||
auto c = parse_color(text.substr(colon+1, pos-colon-2));
|
||||
if (c) {
|
||||
colors.push_back(*c);
|
||||
} else {
|
||||
queue_message(MESSAGE_WARNING, _("Invalid color in tagged string: ") + text.substr(colon + 1, pos - colon - 2));
|
||||
colors.push_back(style.font.color);
|
||||
}
|
||||
}
|
||||
} else if (is_substr(text, tag_start, _("</color"))) {
|
||||
if (!colors.empty()) colors.pop_back();
|
||||
|
||||
@@ -94,7 +94,7 @@ SCRIPT_FUNCTION(recolor_image) {
|
||||
SCRIPT_OPTIONAL_PARAM(Color, red) {
|
||||
SCRIPT_PARAM(Color, green);
|
||||
SCRIPT_PARAM(Color, blue);
|
||||
SCRIPT_PARAM_DEFAULT(Color, white, *wxWHITE);
|
||||
SCRIPT_PARAM_DEFAULT(Color, white, Color(255,255,255));
|
||||
return make_intrusive<RecolorImage2>(input,red,green,blue,white);
|
||||
} else {
|
||||
SCRIPT_PARAM(Color, color);
|
||||
|
||||
@@ -341,11 +341,11 @@ public:
|
||||
}
|
||||
}
|
||||
Color toColor() const override {
|
||||
Color c = parse_color(value);
|
||||
if (!c.Ok()) {
|
||||
optional<Color> c = parse_color(value);
|
||||
if (!c.has_value()) {
|
||||
throw ScriptErrorConversion(value, typeName(), _TYPE_("color"));
|
||||
}
|
||||
return c;
|
||||
return *c;
|
||||
}
|
||||
wxDateTime toDateTime() const override {
|
||||
wxDateTime date;
|
||||
|
||||
@@ -52,7 +52,6 @@ typedef wxWindow Window;
|
||||
|
||||
typedef wxBitmap Bitmap;
|
||||
typedef wxImage Image;
|
||||
typedef wxColour Color;
|
||||
typedef wxDC DC;
|
||||
|
||||
typedef wxDateTime DateTime;
|
||||
|
||||
@@ -182,11 +182,11 @@ RotatedDC::RotatedDC(DC& dc, const Rotation& rotation, RenderQuality quality)
|
||||
|
||||
// ----------------------------------------------------------------------------- : RotatedDC : Drawing
|
||||
|
||||
void RotatedDC::DrawText (const String& text, const RealPoint& pos, int blur_radius, int boldness, double stretch_) {
|
||||
void RotatedDC::DrawText(const String& text, const RealPoint& pos, int blur_radius, int boldness, double stretch_) {
|
||||
DrawText(text, pos, dc.GetTextForeground(), blur_radius, boldness, stretch_);
|
||||
}
|
||||
|
||||
void RotatedDC::DrawText (const String& text, const RealPoint& pos, Color color, int blur_radius, int boldness, double stretch_) {
|
||||
void RotatedDC::DrawText(const String& text, const RealPoint& pos, Color color, int blur_radius, int boldness, double stretch_) {
|
||||
if (text.empty()) return;
|
||||
if (color.Alpha() == 0) return;
|
||||
if (quality >= QUALITY_AA) {
|
||||
|
||||
Reference in New Issue
Block a user