Skip to content

Commit

Permalink
Add styles to most elements
Browse files Browse the repository at this point in the history
  • Loading branch information
rubenwardy committed Aug 3, 2019
1 parent ec3795a commit 9541165
Show file tree
Hide file tree
Showing 9 changed files with 284 additions and 100 deletions.
1 change: 1 addition & 0 deletions build/android/jni/Android.mk
Expand Up @@ -177,6 +177,7 @@ LOCAL_SRC_FILES := \
jni/src/filesys.cpp \
jni/src/genericobject.cpp \
jni/src/gettext.cpp \
jni/src/gui/guiButton.cpp \
jni/src/gui/guiChatConsole.cpp \
jni/src/gui/guiConfirmRegistration.cpp \
jni/src/gui/guiEditBoxWithScrollbar.cpp \
Expand Down
2 changes: 1 addition & 1 deletion builtin/mainmenu/dlg_delete_content.lua
Expand Up @@ -22,7 +22,7 @@ local function delete_content_formspec(dialogdata)
"size[11.5,4.5,true]" ..
"label[2,2;" ..
fgettext("Are you sure you want to delete \"$1\"?", dialogdata.content.name) .. "]"..
"style[dlg_delete_content_confirm;bgcolor;red]" ..
"style[dlg_delete_content_confirm;bgcolor=red]" ..
"button[3.25,3.5;2.5,0.5;dlg_delete_content_confirm;" .. fgettext("Delete") .. "]" ..
"button[5.75,3.5;2.5,0.5;dlg_delete_content_cancel;" .. fgettext("Cancel") .. "]"

Expand Down
2 changes: 1 addition & 1 deletion builtin/mainmenu/dlg_delete_world.lua
Expand Up @@ -21,7 +21,7 @@ local function delete_world_formspec(dialogdata)
"size[10,2.5,true]" ..
"label[0.5,0.5;" ..
fgettext("Delete World \"$1\"?", dialogdata.delete_name) .. "]" ..
"style[world_delete_confirm;bgcolor;red]" ..
"style[world_delete_confirm;bgcolor=red]" ..
"button[0.5,1.5;2.5,0.5;world_delete_confirm;" .. fgettext("Delete") .. "]" ..
"button[7.0,1.5;2.5,0.5;world_delete_cancel;" .. fgettext("Cancel") .. "]"
return retval
Expand Down
3 changes: 0 additions & 3 deletions builtin/mainmenu/tab_local.lua
Expand Up @@ -102,9 +102,6 @@ local function get_formspec(tabview, name, tabdata)
)

retval = retval ..
"style_type[button;bgcolor;#006699]" ..
"style[world_delete;bgcolor;red]" ..
"style[world_delete;textcolor;yellow]" ..
"button[4,3.95;2.6,1;world_delete;".. fgettext("Delete") .. "]" ..
"button[6.5,3.95;2.8,1;world_configure;".. fgettext("Configure") .. "]" ..
"button[9.2,3.95;2.5,1;world_create;".. fgettext("New") .. "]" ..
Expand Down
103 changes: 78 additions & 25 deletions doc/lua_api.txt
Expand Up @@ -1884,7 +1884,10 @@ When displaying text which can contain formspec code, e.g. text set by a player,
use `minetest.formspec_escape`.
For coloured text you can use `minetest.colorize`.

WARNING: Minetest allows you to add elements to every single formspec instance
**WARNING**: do _not_ use a element name starting with `key_`; those names are
reserved to pass key press events to formspec!

**WARNING**: Minetest allows you to add elements to every single formspec instance
using `player:set_formspec_prepend()`, which may be the reason backgrounds are
appearing when you don't expect them to, or why things are styled differently
to normal. See [`no_prepend[]`] and [Styling Formspecs].
Expand Down Expand Up @@ -2351,22 +2354,17 @@ Elements
* `span=<value>`: number of following columns to affect
(default: infinite).

**Note**: do _not_ use a element name starting with `key_`; those names are
reserved to pass key press events to formspec!

### `style[<name>;<propery>;<value]`
### `style[<name>;<prop1>;<prop2>;...]`

Set the style for the named element `name`.
Note: this **must** be before the element's tag.
* Set the style for the named element `name`.
* Note: this **must** be before the element is defined.
* See [Styling Formspecs].

See [Styling Formspecs].

### `style_type[<type>;<prop1>;<prop2>;...]`

### `style_type[<type>;<propery>;<value>]`

Sets the style for all elements of type `type` which appear after this tag.

See [Styling Formspecs].
* Sets the style for all elements of type `type` which appear after this element.
* See [Styling Formspecs].

Migrating to Real Coordinates
-----------------------------
Expand Down Expand Up @@ -2406,27 +2404,82 @@ offsets when migrating:
Styling Formspecs
-----------------

Formspec elements can be themed using the style tags:
Formspec elements can be themed using the style elements:

style[<name>;<prop1>;<prop2>;...]
style_type[<type>;<prop1>;<prop2>;...]

Where a prop is:

style[ELEMENT_NAME;PROPERTY;VALUE]
style_type[ELEMENT_TYPE;PROPERTY;VALUE]
property_name=property_value

For example:

style_type[button;bgcolor;#006699]
style[world_delete;bgcolor;#ff0000]
button[4,3.95;2.6,1;world_delete;Delete]
style_type[button;bgcolor=#006699]
style[world_delete;bgcolor=red;textcolor=yellow]
button[4,3.95;2.6,1;world_delete;Delete]

### Valid Properties
Setting a property to nothing will reset it to the default value. For example:

style_type[button;bgimg=button.png;bgimg_pressed=button_pressed.png;border=false]
style[btn_exit;bgimg=;bgimg_pressed=;border=;bgcolor=red]


### Supported Element Types

* button and button_exit
* bgcolor - sets button tint
* textcolor
Some types may inherit styles from parent types.

* button
* button_exit, inherits from button
* checkbox
* scrollbar
* table
* textlist
* dropdown
* field
* pwdfield, inherits from field
* textarea
* label
* vertlabel, inherits from field
* image_button
* item_image_button, inherits from image_button
* tabheader
* bgcolor - tab background
* textcolor


### Valid Properties

* button, button_exit
* bgcolor - color, sets button tint
* textcolor - color, default white
* border - boolean, draw border. Set to false to hide the bevelled button pane. Default true.
* noclip - boolean, set to true to allow the element to exceed formspec bounds.
* bgimg - standard image. Defaults to none.
* bgimg_pressed - image when pressed. Defaults to bgimg when not provided.
* alpha - boolean, whether to draw alpha in bgimg. Default true.
* checkbox
* noclip - boolean, set to true to allow the element to exceed formspec bounds.
* scrollbar
* noclip - boolean, set to true to allow the element to exceed formspec bounds.
* table, textlist
* noclip - boolean, set to true to allow the element to exceed formspec bounds.
* dropdown
* noclip - boolean, set to true to allow the element to exceed formspec bounds.
* field, pwdfield, textarea
* noclip - boolean, set to true to allow the element to exceed formspec bounds.
* border - set to false to hide the textbox background and border. Default true.
* textcolor - color. Default white.
* label, vertlabel
* bgcolor - color. Default unset.
* textcolor - color. Default white.
* noclip - boolean, set to true to allow the element to exceed formspec bounds.
* border - boolean, set to true to get a border. Default true.
* image_button, item_image_button
* noclip - boolean, set to true to allow the element to exceed formspec bounds.
* border - boolean, draw border. Set to false to hide the bevelled button pane. Default false.
* alpha - boolean, whether to draw alpha in bgimg. Default true.
* tabheader
* noclip - boolean, set to true to allow the element to exceed formspec bounds.
* textcolor - color. Default white.

Inventory
=========
Expand Down
16 changes: 8 additions & 8 deletions src/client/renderingengine.cpp
Expand Up @@ -55,17 +55,17 @@ with this program; if not, write to the Free Software Foundation, Inc.,
RenderingEngine *RenderingEngine::s_singleton = nullptr;


static gui::GUISkin* createSkin(gui::IGUIEnvironment *environment,
gui::EGUI_SKIN_TYPE type, video::IVideoDriver *driver)
static gui::GUISkin *createSkin(gui::IGUIEnvironment *environment,
gui::EGUI_SKIN_TYPE type, video::IVideoDriver *driver)
{
gui::GUISkin* skin = new gui::GUISkin(type, driver);
gui::GUISkin *skin = new gui::GUISkin(type, driver);

gui::IGUIFont* builtinfont = environment->getBuiltInFont();
gui::IGUIFontBitmap* bitfont = 0;
gui::IGUIFont *builtinfont = environment->getBuiltInFont();
gui::IGUIFontBitmap *bitfont = nullptr;
if (builtinfont && builtinfont->getType() == gui::EGFT_BITMAP)
bitfont = (gui::IGUIFontBitmap*)builtinfont;

gui::IGUISpriteBank* bank = 0;
gui::IGUISpriteBank *bank = 0;
skin->setFont(builtinfont);

if (bitfont)
Expand Down Expand Up @@ -102,7 +102,7 @@ RenderingEngine::RenderingEngine(IEventReceiver *receiver)
u32 i;
for (i = 0; i != drivers.size(); i++) {
if (!strcasecmp(driverstring.c_str(),
RenderingEngine::getVideoDriverName(drivers[i]))) {
RenderingEngine::getVideoDriverName(drivers[i]))) {
driverType = drivers[i];
break;
}
Expand Down Expand Up @@ -139,7 +139,7 @@ RenderingEngine::RenderingEngine(IEventReceiver *receiver)
s_singleton = this;

auto skin = createSkin(m_device->getGUIEnvironment(),
gui::EGST_WINDOWS_METALLIC, driver);
gui::EGST_WINDOWS_METALLIC, driver);
m_device->getGUIEnvironment()->setSkin(skin);
skin->drop();
}
Expand Down
93 changes: 63 additions & 30 deletions src/gui/StyleSpec.h
Expand Up @@ -18,85 +18,118 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/

#include "irrlichttypes_extrabloated.h"
#include <array>

#pragma once


class StyleSpec
{
public:
enum Property {
NONE = 0,
enum Property
{
TEXTCOLOR,
BGCOLOR,
NUM_PROPERTIES
NOCLIP,
BORDER,
BGIMG,
BGIMG_PRESSED,
ALPHA,
NUM_PROPERTIES,
NONE
};

private:
std::unordered_map<Property, std::string> properties;
std::array<bool, NUM_PROPERTIES> property_set;
std::array<std::string, NUM_PROPERTIES> properties;

public:
static Property GetPropertyByName(const std::string &name) {
static Property GetPropertyByName(const std::string &name)
{
if (name == "textcolor") {
return TEXTCOLOR;
} else if (name == "bgcolor") {
return BGCOLOR;
} else if (name == "noclip") {
return NOCLIP;
} else if (name == "border") {
return BORDER;
} else if (name == "bgimg") {
return BGIMG;
} else if (name == "bgimg_pressed") {
return BGIMG_PRESSED;
} else if (name == "alpha") {
return ALPHA;
} else {
return NONE;
}
}

std::string get(Property prop, std::string def) const {
auto it = properties.find(prop);
if (it == properties.end()) {
return def;
}

return it->second;
std::string get(Property prop, std::string def) const
{
const auto &val = properties[prop];
return val.empty() ? def : val;
}

void set(Property prop, std::string value) {
properties[prop] = std::move(value);
void set(Property prop, const std::string &value)
{
properties[prop] = value;
property_set[prop] = true;
}

video::SColor getColor(Property prop, video::SColor def) const {
auto it = properties.find(prop);
if (it == properties.end()) {
video::SColor getColor(Property prop, video::SColor def) const
{
const auto &val = properties[prop];
if (val.empty()) {
return def;
}

parseColorString(it->second, def, false, 0xFF);
parseColorString(val, def, false, 0xFF);
return def;
}

video::SColor getColor(Property prop) const {
auto it = properties.find(prop);
FATAL_ERROR_IF(it == properties.end(), "Unexpected missing property");
video::SColor getColor(Property prop) const
{
const auto &val = properties[prop];
FATAL_ERROR_IF(val.empty(), "Unexpected missing property");

video::SColor color;
parseColorString(it->second, color, false, 0xFF);
parseColorString(val, color, false, 0xFF);
return color;
}

bool hasProperty(Property prop) const {
return properties.find(prop) != properties.end();
bool getBool(Property prop, bool def) const
{
const auto &val = properties[prop];
if (val.empty()) {
return def;
}

return is_yes(val);
}

inline bool isNotDefault(Property prop) const
{
return !properties[prop].empty();
}

StyleSpec &operator|=(const StyleSpec &other) {
for (size_t i = 1; i < NUM_PROPERTIES; i++) {
inline bool hasProperty(Property prop) const { return property_set[prop]; }

StyleSpec &operator|=(const StyleSpec &other)
{
for (size_t i = 0; i < NUM_PROPERTIES; i++) {
auto prop = (Property)i;
if (other.hasProperty(prop)) {
properties[prop] = other.get(prop, "");
set(prop, other.get(prop, ""));
}
}

return *this;
}

StyleSpec operator|(const StyleSpec &other) const {
StyleSpec operator|(const StyleSpec &other) const
{
StyleSpec newspec = *this;
newspec |= other;
return newspec;
}
};

0 comments on commit 9541165

Please sign in to comment.