allow specifying color, percentages, and border for LifeBar

This commit is contained in:
Tim Felgentreff 2018-10-27 14:08:12 +00:00
parent 05d1cac88f
commit 8251f91971
4 changed files with 102 additions and 38 deletions

View file

@ -40,7 +40,13 @@
<ul> <ul>
<p/> <p/>
<p/><li>2.4.2 Released<p/></li> <p/><li>2.4.3 Released<p/></li>
<ul>
<li>
Allow specifying colors, percentages, and border for the LifeBar.
</li>
</ul>
</li><p/><li>2.4.2 Released<p/></li>
<ul> <ul>
<li> <li>
Force load progress to screen only every 500ms. On modern machines, loading Force load progress to screen only every 500ms. On modern machines, loading

View file

@ -918,6 +918,15 @@ Define panel content when an unit is selected.
<dd>Height of the bar.</dd> <dd>Height of the bar.</dd>
<dt>Width = value</dt> <dt>Width = value</dt>
<dd>width of the bar.</dd> <dd>width of the bar.</dd>
<dt>Border = boolean</dt>
<dd>if true then add a border to the bar. Default is true.</dd>
<dt>Colors = list</dt>
<dd>A list of {percentage, color-name} pairs. The default is equivalent
to {{75, "dark-green"}, {50, "yellow"}, {25, "orange"}, {0,
"red"}}. The last element must start with "0". The meaning of the
number is the percentage above which the associated color takes
effect.
</dd>
</dl></dd> </dl></dd>
<dt>"CompleteBar", {flag = value, ...}</dt> <dt>"CompleteBar", {flag = value, ...}</dt>
<dd>Draw a bar which represent the variable. <dd>Draw a bar which represent the variable.

View file

@ -149,19 +149,23 @@ private:
class CContentTypeLifeBar : public CContentType class CContentTypeLifeBar : public CContentType
{ {
public: public:
CContentTypeLifeBar() : Index(-1), Width(0), Height(0) {} CContentTypeLifeBar() : Index(-1), Width(0), Height(0), hasBorder(true), colors(NULL), values(NULL) {}
virtual ~CContentTypeLifeBar()
{
delete[] colors;
delete[] values;
}
virtual void Draw(const CUnit &unit, CFont *defaultfont) const; virtual void Draw(const CUnit &unit, CFont *defaultfont) const;
virtual void Parse(lua_State *l); virtual void Parse(lua_State *l);
private: private:
int Index; /// Index of the variable to show, -1 if not. int Index; /// Index of the variable to show, -1 if not.
int Width; /// Width of the bar. int Width; /// Width of the bar.
int Height; /// Height of the bar. int Height; /// Height of the bar.
#if 0 // FIXME : something for color and value parametrisation (not implemented) bool hasBorder; /// True for additional border.
Color *colors; /// array of color to show (depend of value) unsigned int *colors; /// array of color to show (depend of value)
int *values; /// list of percentage to change color. unsigned int *values; /// list of percentage to change color.
#endif
}; };
/** /**

View file

@ -262,6 +262,30 @@ static const CUnit *GetUnitRef(const CUnit &unit, EnumUnit e)
} }
} }
static inline Uint32 IndexToColor(unsigned int index) {
// FIXME: this only works after video was initialized, so we do it dynamically
static const Uint32 ColorValues[] = {ColorRed, ColorYellow, ColorGreen, ColorLightGray,
ColorGray, ColorDarkGray, ColorWhite, ColorOrange,
ColorLightBlue, ColorBlue, ColorDarkGreen, ColorBlack};
return ColorValues[index];
}
static const char *ColorNames[] = {"red", "yellow", "green", "light-gray",
"gray", "dark-gray", "white", "orange",
"light-blue", "blue", "dark-green", "black", NULL};
static int GetColorIndexByName(const char *colorName)
{
int i = 0;
while (ColorNames[i] != NULL) {
if (!strcmp(colorName, ColorNames[i])) {
return i;
}
i++;
}
return -1;
}
/** /**
** Draw life bar of a unit using selected variable. ** Draw life bar of a unit using selected variable.
** Placed under icons on top-panel. ** Placed under icons on top-panel.
@ -280,20 +304,19 @@ static const CUnit *GetUnitRef(const CUnit &unit, EnumUnit e)
Uint32 color; Uint32 color;
int f = (100 * unit.Variable[this->Index].Value) / unit.Variable[this->Index].Max; int f = (100 * unit.Variable[this->Index].Value) / unit.Variable[this->Index].Max;
int i = 0;
if (f > 75) { // get to right color
color = ColorDarkGreen; while (f < this->values[i]) {
} else if (f > 50) { i++;
color = ColorYellow;
} else if (f > 25) {
color = ColorOrange;
} else {
color = ColorRed;
} }
color = IndexToColor(this->colors[i]);
// Border if (this->hasBorder) {
Video.FillRectangleClip(ColorBlack, this->Pos.x - 2, this->Pos.y - 2, // Border
this->Width + 3, this->Height + 3); Video.FillRectangleClip(ColorBlack, this->Pos.x - 2, this->Pos.y - 2,
this->Width + 3, this->Height + 3);
}
Video.FillRectangleClip(color, this->Pos.x - 1, this->Pos.y - 1, Video.FillRectangleClip(color, this->Pos.x - 1, this->Pos.y - 1,
(f * this->Width) / 100, this->Height); (f * this->Width) / 100, this->Height);
@ -320,11 +343,7 @@ static const CUnit *GetUnitRef(const CUnit &unit, EnumUnit e)
int h = this->height; int h = this->height;
Assert(w > 0); Assert(w > 0);
Assert(h > 4); Assert(h > 4);
const Uint32 colors[] = {ColorRed, ColorYellow, ColorGreen, ColorLightGray, const Uint32 color = (colorIndex != -1) ? IndexToColor(colorIndex) : UI.CompletedBarColor;
ColorGray, ColorDarkGray, ColorWhite, ColorOrange,
ColorLightBlue, ColorBlue, ColorDarkGreen, ColorBlack
};
const Uint32 color = (colorIndex != -1) ? colors[colorIndex] : UI.CompletedBarColor;
const int f = (100 * unit.Variable[this->varIndex].Value) / unit.Variable[this->varIndex].Max; const int f = (100 * unit.Variable[this->varIndex].Value) / unit.Variable[this->varIndex].Max;
if (!this->hasBorder) { if (!this->hasBorder) {
@ -508,6 +527,34 @@ static EnumUnit Str2EnumUnit(lua_State *l, const char *s)
this->Height = LuaToNumber(l, -1); this->Height = LuaToNumber(l, -1);
} else if (!strcmp(key, "Width")) { } else if (!strcmp(key, "Width")) {
this->Width = LuaToNumber(l, -1); this->Width = LuaToNumber(l, -1);
} else if (!strcmp(key, "Colors")) {
if (!lua_istable(l, -1)) {
LuaError(l, "incorrect argument, need list");
}
const int color_len = lua_rawlen(l, -1);
if (color_len == 0) {
LuaError(l, "need at least one {percentage, color} pair, got 0");
}
this->colors = new unsigned int[color_len];
this->values = new unsigned int[color_len];
int i = 0;
for (lua_pushnil(l); lua_next(l, -2); lua_pop(l, 1)) {
if (!lua_istable(l, -1) || lua_rawlen(l, -1) != 2) {
LuaError(l, "incorrect argument, need list of size 2 with {percentage, color}");
}
this->values[i] = LuaToNumber(l, -1, 1);
const char *const colorName = LuaToString(l, -1, 2);
this->colors[i] = GetColorIndexByName(colorName);
if (this->colors[i] == -1) {
LuaError(l, "incorrect color: '%s' " _C_ colorName);
}
i++;
}
if (this->values[color_len - 1] != 0) {
LuaError(l, "the last {percentage, color} pair must be for 0%%");
}
} else if (!strcmp(key, "Border")) {
this->hasBorder = LuaToBoolean(l, -1);
} else { } else {
LuaError(l, "'%s' invalid for method 'LifeBar' in DefinePanelContents" _C_ key); LuaError(l, "'%s' invalid for method 'LifeBar' in DefinePanelContents" _C_ key);
} }
@ -522,22 +569,20 @@ static EnumUnit Str2EnumUnit(lua_State *l, const char *s)
if (this->Index == -1) { if (this->Index == -1) {
LuaError(l, "variable undefined for LifeBar"); LuaError(l, "variable undefined for LifeBar");
} }
} if (this->colors == NULL || this->values == NULL) {
this->colors = new unsigned int[4];
this->values = new unsigned int[4];
static int GetColorIndexByName(const char *colorName) this->values[0] = 75;
{ this->values[1] = 50;
//FIXME: need more general way this->values[2] = 25;
const char *names[] = { this->values[3] = 0;
"red", "yellow", "green", "light-gray", "gray", "dark-gray",
"white", "orange", "light-blue", "blue", "dark-green", "black"
};
for (unsigned int i = 0; i != sizeof(names) / sizeof(names[0]); ++i) { this->colors[0] = GetColorIndexByName("dark-green");
if (!strcmp(colorName, names[i])) { this->colors[1] = GetColorIndexByName("yellow");
return i; this->colors[2] = GetColorIndexByName("orange");;
} this->colors[3] = GetColorIndexByName("red");
} }
return -1;
} }
/* virtual */ void CContentTypeCompleteBar::Parse(lua_State *l) /* virtual */ void CContentTypeCompleteBar::Parse(lua_State *l)