mirror of
https://github.com/minetest/minetest.git
synced 2024-12-23 14:42:24 +01:00
Add [colorize modifier
This commit is contained in:
parent
173beeee65
commit
28438bba27
@ -262,6 +262,10 @@ Advanced texture modifiers:
|
||||
Apply a mask to the base image.
|
||||
The mask is applied using binary AND.
|
||||
|
||||
[colorize:<color>
|
||||
Colorize the textures with given color
|
||||
<color> as ColorString
|
||||
|
||||
Sounds
|
||||
-------
|
||||
Only OGG Vorbis files are supported.
|
||||
@ -985,16 +989,16 @@ list[<inventory location>;<list name>;<X>,<Y>;<W>,<H>;<starting item index>]
|
||||
^ Show an inventory list
|
||||
|
||||
listcolors[<slot_bg_normal>;<slot_bg_hover>]
|
||||
^ Sets background color of slots in HEX-Color format
|
||||
^ Sets background color of slots as ColorString
|
||||
^ Sets background color of slots on mouse hovering
|
||||
|
||||
listcolors[<slot_bg_normal>;<slot_bg_hover>;<slot_border>]
|
||||
^ Sets background color of slots in HEX-Color format
|
||||
^ Sets background color of slots as ColorString
|
||||
^ Sets background color of slots on mouse hovering
|
||||
^ Sets color of slots border
|
||||
|
||||
listcolors[<slot_bg_normal>;<slot_bg_hover>;<slot_border>;<tooltip_bgcolor>;<tooltip_fontcolor>]
|
||||
^ Sets background color of slots in HEX-Color format
|
||||
^ Sets background color of slots as ColorString
|
||||
^ Sets background color of slots on mouse hovering
|
||||
^ Sets color of slots border
|
||||
^ Sets default background color of tooltips
|
||||
@ -1002,8 +1006,8 @@ listcolors[<slot_bg_normal>;<slot_bg_hover>;<slot_border>;<tooltip_bgcolor>;<too
|
||||
|
||||
tooltip[<gui_element_name>;<tooltip_text>;<bgcolor>,<fontcolor>]
|
||||
^ Adds tooltip for an element
|
||||
^ <bgcolor> tooltip background color in HEX-Color format (optional)
|
||||
^ <fontcolor> tooltip font color in HEX-Color format (optional)
|
||||
^ <bgcolor> tooltip background color as ColorString (optional)
|
||||
^ <fontcolor> tooltip font color as ColorString (optional)
|
||||
|
||||
|
||||
image[<X>,<Y>;<W>,<H>;<texture name>]
|
||||
@ -1015,7 +1019,7 @@ item_image[<X>,<Y>;<W>,<H>;<item name>]
|
||||
^ Position and size units are inventory slots
|
||||
|
||||
bgcolor[<color>;<fullscreen>]
|
||||
^ Sets background color of formspec in HEX-Color format
|
||||
^ Sets background color of formspec as ColorString
|
||||
^ If true the background color is drawn fullscreen (does not effect the size of the formspec)
|
||||
|
||||
background[<X>,<Y>;<W>,<H>;<texture name>]
|
||||
@ -1136,7 +1140,7 @@ box[<X>,<Y>;<W>,<H>;<color>]
|
||||
^ simple colored semitransparent box
|
||||
^ x and y position the box relative to the top left of the menu
|
||||
^ w and h are the size of box
|
||||
^ color in HEX-Color format
|
||||
^ color as ColorString
|
||||
|
||||
dropdown[<X>,<Y>;<W>;<name>;<item 1>,<item 2>, ...,<item n>;<selected idx>]
|
||||
^ show a dropdown field
|
||||
@ -1182,15 +1186,15 @@ table[<X>,<Y>;<W>,<H>;<name>;<cell 1>,<cell 2>,...,<cell n>;<selected idx>]
|
||||
tableoptions[<opt 1>;<opt 2>;...]
|
||||
^ sets options for table[]:
|
||||
^ color=#RRGGBB
|
||||
^^ default text color (HEX-Color), defaults to #FFFFFF
|
||||
^^ default text color (ColorString), defaults to #FFFFFF
|
||||
^ background=#RRGGBB
|
||||
^^ table background color (HEX-Color), defaults to #000000
|
||||
^^ table background color (ColorString), defaults to #000000
|
||||
^ border=<true/false>
|
||||
^^ should the table be drawn with a border? (default true)
|
||||
^ highlight=#RRGGBB
|
||||
^^ highlight background color (HEX-Color), defaults to #466432
|
||||
^^ highlight background color (ColorString), defaults to #466432
|
||||
^ highlight_text=#RRGGBB
|
||||
^^ highlight text color (HEX-Color), defaults to #FFFFFF
|
||||
^^ highlight text color (ColorString), defaults to #FFFFFF
|
||||
^ opendepth=<value>
|
||||
^^ all subtrees up to depth < value are open (default value = 0)
|
||||
^^ only useful when there is a column of type "tree"
|
||||
@ -1200,7 +1204,7 @@ tablecolumns[<type 1>,<opt 1a>,<opt 1b>,...;<type 2>,<opt 2a>,<opt 2b>;...]
|
||||
^ types: text, image, color, indent, tree
|
||||
^^ text: show cell contents as text
|
||||
^^ image: cell contents are an image index, use column options to define images
|
||||
^^ color: cell contents are a HEX-Color and define color of following cell
|
||||
^^ color: cell contents are a ColorString and define color of following cell
|
||||
^^ indent: cell contents are a number and define indentation of following cell
|
||||
^^ tree: same as indent, but user can open and close subtrees (treeview-like)
|
||||
^ column options:
|
||||
@ -1231,8 +1235,8 @@ Inventory location:
|
||||
- "nodemeta:<X>,<Y>,<Z>": Any node metadata
|
||||
- "detached:<name>": A detached inventory
|
||||
|
||||
HEX-Color
|
||||
---------
|
||||
ColorString
|
||||
-----------
|
||||
#RGB
|
||||
^ defines a color in hexadecimal format
|
||||
#RGBA
|
||||
|
@ -50,6 +50,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "main.h"
|
||||
#include "settings.h"
|
||||
#include "client.h"
|
||||
#include "util/string.h" // for parseColorString()
|
||||
|
||||
#define MY_CHECKPOS(a,b) \
|
||||
if (v_pos.size() != 2) { \
|
||||
@ -1575,7 +1576,7 @@ void GUIFormSpecMenu::parseBox(parserData* data,std::string element)
|
||||
|
||||
video::SColor tmp_color;
|
||||
|
||||
if (parseColor(parts[2], tmp_color, false)) {
|
||||
if (parseColorString(parts[2], tmp_color, false)) {
|
||||
BoxDrawSpec spec(pos, geom, tmp_color);
|
||||
|
||||
m_boxes.push_back(spec);
|
||||
@ -1595,7 +1596,7 @@ void GUIFormSpecMenu::parseBackgroundColor(parserData* data,std::string element)
|
||||
if (((parts.size() == 1) || (parts.size() == 2)) ||
|
||||
((parts.size() > 2) && (m_formspec_version > FORMSPEC_API_VERSION)))
|
||||
{
|
||||
parseColor(parts[0],m_bgcolor,false);
|
||||
parseColorString(parts[0],m_bgcolor,false);
|
||||
|
||||
if (parts.size() == 2) {
|
||||
std::string fullscreen = parts[1];
|
||||
@ -1613,20 +1614,20 @@ void GUIFormSpecMenu::parseListColors(parserData* data,std::string element)
|
||||
if (((parts.size() == 2) || (parts.size() == 3) || (parts.size() == 5)) ||
|
||||
((parts.size() > 5) && (m_formspec_version > FORMSPEC_API_VERSION)))
|
||||
{
|
||||
parseColor(parts[0], m_slotbg_n, false);
|
||||
parseColor(parts[1], m_slotbg_h, false);
|
||||
parseColorString(parts[0], m_slotbg_n, false);
|
||||
parseColorString(parts[1], m_slotbg_h, false);
|
||||
|
||||
if (parts.size() >= 3) {
|
||||
if (parseColor(parts[2], m_slotbordercolor, false)) {
|
||||
if (parseColorString(parts[2], m_slotbordercolor, false)) {
|
||||
m_slotborder = true;
|
||||
}
|
||||
}
|
||||
if (parts.size() == 5) {
|
||||
video::SColor tmp_color;
|
||||
|
||||
if (parseColor(parts[3], tmp_color, false))
|
||||
if (parseColorString(parts[3], tmp_color, false))
|
||||
m_default_tooltip_bgcolor = tmp_color;
|
||||
if (parseColor(parts[4], tmp_color, false))
|
||||
if (parseColorString(parts[4], tmp_color, false))
|
||||
m_default_tooltip_color = tmp_color;
|
||||
}
|
||||
return;
|
||||
@ -1644,7 +1645,7 @@ void GUIFormSpecMenu::parseTooltip(parserData* data, std::string element)
|
||||
} else if (parts.size() == 4) {
|
||||
std::string name = parts[0];
|
||||
video::SColor tmp_color1, tmp_color2;
|
||||
if ( parseColor(parts[2], tmp_color1, false) && parseColor(parts[3], tmp_color2, false) ) {
|
||||
if ( parseColorString(parts[2], tmp_color1, false) && parseColorString(parts[3], tmp_color2, false) ) {
|
||||
m_tooltips[narrow_to_wide(name.c_str())] = TooltipSpec (parts[1], tmp_color1, tmp_color2);
|
||||
return;
|
||||
}
|
||||
@ -3388,67 +3389,3 @@ std::wstring GUIFormSpecMenu::getLabelByID(s32 id)
|
||||
}
|
||||
return L"";
|
||||
}
|
||||
|
||||
bool GUIFormSpecMenu::parseColor(const std::string &value, video::SColor &color,
|
||||
bool quiet)
|
||||
{
|
||||
const char *hexpattern = NULL;
|
||||
if (value[0] == '#') {
|
||||
if (value.size() == 9)
|
||||
hexpattern = "#RRGGBBAA";
|
||||
else if (value.size() == 7)
|
||||
hexpattern = "#RRGGBB";
|
||||
else if (value.size() == 5)
|
||||
hexpattern = "#RGBA";
|
||||
else if (value.size() == 4)
|
||||
hexpattern = "#RGB";
|
||||
}
|
||||
|
||||
if (hexpattern) {
|
||||
assert(strlen(hexpattern) == value.size());
|
||||
video::SColor outcolor(255, 255, 255, 255);
|
||||
for (size_t pos = 0; pos < value.size(); ++pos) {
|
||||
// '#' in the pattern means skip that character
|
||||
if (hexpattern[pos] == '#')
|
||||
continue;
|
||||
|
||||
// Else assume hexpattern[pos] is one of 'R' 'G' 'B' 'A'
|
||||
// Read one or two digits, depending on hexpattern
|
||||
unsigned char c1, c2;
|
||||
if (hexpattern[pos+1] == hexpattern[pos]) {
|
||||
// Two digits, e.g. hexpattern == "#RRGGBB"
|
||||
if (!hex_digit_decode(value[pos], c1) ||
|
||||
!hex_digit_decode(value[pos+1], c2))
|
||||
goto fail;
|
||||
++pos;
|
||||
}
|
||||
else {
|
||||
// One digit, e.g. hexpattern == "#RGB"
|
||||
if (!hex_digit_decode(value[pos], c1))
|
||||
goto fail;
|
||||
c2 = c1;
|
||||
}
|
||||
u32 colorpart = ((c1 & 0x0f) << 4) | (c2 & 0x0f);
|
||||
|
||||
// Update outcolor with newly read color part
|
||||
if (hexpattern[pos] == 'R')
|
||||
outcolor.setRed(colorpart);
|
||||
else if (hexpattern[pos] == 'G')
|
||||
outcolor.setGreen(colorpart);
|
||||
else if (hexpattern[pos] == 'B')
|
||||
outcolor.setBlue(colorpart);
|
||||
else if (hexpattern[pos] == 'A')
|
||||
outcolor.setAlpha(colorpart);
|
||||
}
|
||||
|
||||
color = outcolor;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Optionally, named colors could be implemented here
|
||||
|
||||
fail:
|
||||
if (!quiet)
|
||||
errorstream<<"Invalid color: \""<<value<<"\""<<std::endl;
|
||||
return false;
|
||||
}
|
||||
|
@ -274,9 +274,6 @@ public:
|
||||
|
||||
GUITable* getTable(std::wstring tablename);
|
||||
|
||||
static bool parseColor(const std::string &value,
|
||||
video::SColor &color, bool quiet);
|
||||
|
||||
#ifdef __ANDROID__
|
||||
bool getAndroidUIInput();
|
||||
#endif
|
||||
|
@ -32,7 +32,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "gettime.h"
|
||||
#include "util/string.h"
|
||||
#include "util/numeric.h"
|
||||
#include "guiFormSpecMenu.h" // for parseColor()
|
||||
#include "util/string.h" // for parseColorString()
|
||||
#include "main.h"
|
||||
#include "settings.h" // for settings
|
||||
#include "porting.h" // for dpi
|
||||
@ -164,7 +164,7 @@ void GUITable::setTextList(const std::vector<std::string> &content,
|
||||
cell->content_index = allocString(s.substr(2));
|
||||
}
|
||||
else if (s[0] == '#' && s.size() >= 7 &&
|
||||
GUIFormSpecMenu::parseColor(
|
||||
parseColorString(
|
||||
s.substr(0,7), cell->color, false)) {
|
||||
// single # for color
|
||||
cell->color_defined = true;
|
||||
@ -211,15 +211,15 @@ void GUITable::setTable(const TableOptions &options,
|
||||
const std::string &name = options[k].name;
|
||||
const std::string &value = options[k].value;
|
||||
if (name == "color")
|
||||
GUIFormSpecMenu::parseColor(value, m_color, false);
|
||||
parseColorString(value, m_color, false);
|
||||
else if (name == "background")
|
||||
GUIFormSpecMenu::parseColor(value, m_background, false);
|
||||
parseColorString(value, m_background, false);
|
||||
else if (name == "border")
|
||||
m_border = is_yes(value);
|
||||
else if (name == "highlight")
|
||||
GUIFormSpecMenu::parseColor(value, m_highlight, false);
|
||||
parseColorString(value, m_highlight, false);
|
||||
else if (name == "highlight_text")
|
||||
GUIFormSpecMenu::parseColor(value, m_highlight_text, false);
|
||||
parseColorString(value, m_highlight_text, false);
|
||||
else if (name == "opendepth")
|
||||
opendepth = stoi(value);
|
||||
else
|
||||
@ -416,7 +416,7 @@ void GUITable::setTable(const TableOptions &options,
|
||||
else if (columntype == COLUMN_TYPE_COLOR) {
|
||||
for (s32 i = 0; i < rowcount; ++i) {
|
||||
video::SColor cellcolor(255, 255, 255, 255);
|
||||
if (GUIFormSpecMenu::parseColor(content[i * colcount + j], cellcolor, true))
|
||||
if (parseColorString(content[i * colcount + j], cellcolor, true))
|
||||
rows[i].colors.push_back(std::make_pair(cellcolor, j+span));
|
||||
}
|
||||
}
|
||||
|
41
src/tile.cpp
41
src/tile.cpp
@ -33,6 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "log.h"
|
||||
#include "gamedef.h"
|
||||
#include "strfnd.h"
|
||||
#include "util/string.h" // for parseColorString()
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include <GLES/gl.h>
|
||||
@ -1588,10 +1589,46 @@ bool TextureSource::generateImagePart(std::string part_of_name,
|
||||
<< filename << "\".";
|
||||
}
|
||||
}
|
||||
/*
|
||||
[colorize:color
|
||||
Overlays image with given color
|
||||
color = color as ColorString
|
||||
*/
|
||||
else if (part_of_name.substr(0,10) == "[colorize:") {
|
||||
Strfnd sf(part_of_name);
|
||||
sf.next(":");
|
||||
std::string color_str = sf.next(":");
|
||||
|
||||
if (baseimg == NULL) {
|
||||
errorstream << "generateImagePart(): baseimg != NULL "
|
||||
<< "for part_of_name=\"" << part_of_name
|
||||
<< "\", cancelling." << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
video::SColor color;
|
||||
if (!parseColorString(color_str, color, false))
|
||||
return false;
|
||||
|
||||
core::dimension2d<u32> dim = baseimg->getDimension();
|
||||
video::IImage *img = driver->createImage(video::ECF_A8R8G8B8, dim);
|
||||
|
||||
if (!img) {
|
||||
errorstream << "generateImagePart(): Could not create image "
|
||||
<< "for part_of_name=\"" << part_of_name
|
||||
<< "\", cancelling." << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
img->fill(video::SColor(color));
|
||||
// Overlay the colored image
|
||||
blit_with_alpha_overlay(img, baseimg, v2s32(0,0), v2s32(0,0), dim);
|
||||
img->drop();
|
||||
}
|
||||
else
|
||||
{
|
||||
errorstream<<"generateImagePart(): Invalid "
|
||||
" modification: \""<<part_of_name<<"\""<<std::endl;
|
||||
errorstream << "generateImagePart(): Invalid "
|
||||
" modification: \"" << part_of_name << "\"" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "string.h"
|
||||
#include "pointer.h"
|
||||
#include "numeric.h"
|
||||
#include "log.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
@ -303,3 +304,65 @@ u64 read_seed(const char *str)
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
bool parseColorString(const std::string &value, video::SColor &color, bool quiet)
|
||||
{
|
||||
const char *hexpattern = NULL;
|
||||
video::SColor outcolor(255, 255, 255, 255);
|
||||
|
||||
if (value[0] == '#') {
|
||||
if (value.size() == 9)
|
||||
hexpattern = "#RRGGBBAA";
|
||||
else if (value.size() == 7)
|
||||
hexpattern = "#RRGGBB";
|
||||
else if (value.size() == 5)
|
||||
hexpattern = "#RGBA";
|
||||
else if (value.size() == 4)
|
||||
hexpattern = "#RGB";
|
||||
}
|
||||
|
||||
if (!hexpattern)
|
||||
goto fail;
|
||||
|
||||
assert(strlen(hexpattern) == value.size());
|
||||
for (size_t pos = 0; pos < value.size(); ++pos) {
|
||||
// '#' in the pattern means skip that character
|
||||
if (hexpattern[pos] == '#')
|
||||
continue;
|
||||
|
||||
// Else assume hexpattern[pos] is one of 'R' 'G' 'B' 'A'
|
||||
// Read one or two digits, depending on hexpattern
|
||||
unsigned char c1, c2;
|
||||
if (hexpattern[pos+1] == hexpattern[pos]) {
|
||||
// Two digits, e.g. hexpattern == "#RRGGBB"
|
||||
if (!hex_digit_decode(value[pos], c1) ||
|
||||
!hex_digit_decode(value[pos+1], c2))
|
||||
goto fail;
|
||||
++pos;
|
||||
} else {
|
||||
// One digit, e.g. hexpattern == "#RGB"
|
||||
if (!hex_digit_decode(value[pos], c1))
|
||||
goto fail;
|
||||
c2 = c1;
|
||||
}
|
||||
u32 colorpart = ((c1 & 0x0f) << 4) | (c2 & 0x0f);
|
||||
|
||||
// Update outcolor with newly read color part
|
||||
if (hexpattern[pos] == 'R')
|
||||
outcolor.setRed(colorpart);
|
||||
else if (hexpattern[pos] == 'G')
|
||||
outcolor.setGreen(colorpart);
|
||||
else if (hexpattern[pos] == 'B')
|
||||
outcolor.setBlue(colorpart);
|
||||
else if (hexpattern[pos] == 'A')
|
||||
outcolor.setAlpha(colorpart);
|
||||
}
|
||||
|
||||
color = outcolor;
|
||||
return true;
|
||||
|
||||
fail:
|
||||
if (!quiet)
|
||||
errorstream << "Invalid color: \"" << value << "\"" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#ifndef UTIL_STRING_HEADER
|
||||
#define UTIL_STRING_HEADER
|
||||
|
||||
#include "../irrlichttypes.h"
|
||||
#include "irrlichttypes_bloated.h"
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
@ -349,6 +349,7 @@ std::string writeFlagString(u32 flags, const FlagDesc *flagdesc, u32 flagmask);
|
||||
size_t mystrlcpy(char *dst, const char *src, size_t size);
|
||||
char *mystrtok_r(char *s, const char *sep, char **lasts);
|
||||
u64 read_seed(const char *str);
|
||||
bool parseColorString(const std::string &value, video::SColor &color, bool quiet);
|
||||
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user