mirror of https://github.com/buggins/dlangui.git
support changing of theme
This commit is contained in:
parent
1f9e1eba27
commit
60776f2ce9
|
@ -0,0 +1,166 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<theme
|
||||
id="theme_custom1"
|
||||
parent="theme_default"
|
||||
fontSize="24"
|
||||
>
|
||||
<style id="BUTTON"
|
||||
backgroundImageId="btn_default_small"
|
||||
align="Center"
|
||||
margins="5,5,5,5"
|
||||
/>
|
||||
<style id="BUTTON_TRANSPARENT"
|
||||
backgroundImageId="btn_default_small_transparent"
|
||||
align="Center"
|
||||
/>
|
||||
<style id="BUTTON_LABEL"
|
||||
layoutWidth="FILL_PARENT"
|
||||
align="Left|VCenter"
|
||||
/>
|
||||
<style id="BUTTON_ICON"
|
||||
align="Center"
|
||||
/>
|
||||
<style id="TEXT"
|
||||
margins="2,2,2,2"
|
||||
padding="1,1,1,1"
|
||||
/>
|
||||
<style id="HSPACER"
|
||||
layoutWidth="FILL_PARENT"
|
||||
layoutWeight="100"
|
||||
minWidth="5"
|
||||
/>
|
||||
<style id="VSPACER"
|
||||
layoutHeight="FILL_PARENT"
|
||||
layoutWeight="100"
|
||||
minHeight="5"
|
||||
/>
|
||||
<style id="BUTTON_NOMARGINS"
|
||||
backgroundImageId="btn_default_small"
|
||||
align="Center"
|
||||
/>
|
||||
<drawable id="scrollbar_button_up" value="scrollbar_btn_up"/>
|
||||
<drawable id="scrollbar_button_down" value="scrollbar_btn_down"/>
|
||||
<srawable id="scrollbar_button_left" value="scrollbar_btn_left"/>
|
||||
<drawable id="scrollbar_button_right" value="scrollbar_btn_right"/>
|
||||
<drawable id="scrollbar_indicator_vertical" value="scrollbar_indicator_vertical"/>
|
||||
<drawable id="scrollbar_indicator_horizontal" value="scrollbar_indicator_horizontal"/>
|
||||
<style id="SCROLLBAR"
|
||||
backgroundColor="#C0808080"
|
||||
align="Center"
|
||||
/>
|
||||
<style id="SCROLLBAR_BUTTON" parent="BUTTON"
|
||||
/>
|
||||
<style id="SLIDER"
|
||||
/>
|
||||
<style id="PAGE_SCROLL"
|
||||
backgroundColor="#FFFFFFFF"
|
||||
>
|
||||
<state state_pressed="true" backgroundColor="#C0404080"/>
|
||||
<state state_hovered="true" backgroundColor="#F0404080"/>
|
||||
</style>
|
||||
<style id="TAB_UP"
|
||||
backgroundImageId="tab_up_background"
|
||||
layoutWidth="FILL_PARENT"
|
||||
>
|
||||
<state state_selected="true" backgroundImageId="tab_up_backgrond_selected"/>
|
||||
</style>
|
||||
<style id="TAB_UP_BUTTON_TEXT"
|
||||
textColor="#000000"
|
||||
fontSize="16"
|
||||
align="Center"
|
||||
>
|
||||
<state state_selected="true" state_focused="true" textColor="#000000"/>
|
||||
<state state_selected="true" textColor="#000000"/>
|
||||
<state state_focused="true" textColor="#000000"/>
|
||||
<state state_hovered="true" textColor="#FFE0E0"/>
|
||||
</style>
|
||||
<style id="TAB_UP_BUTTON"
|
||||
backgroundImageId="tab_btn_up"
|
||||
/>
|
||||
<style id="TAB_HOST"
|
||||
layoutWidth="FILL_PARENT"
|
||||
layoutHeight="FILL_PARENT"
|
||||
backgroundColor="#F0F0F0"
|
||||
/>
|
||||
<style id="TAB_WIDGET"
|
||||
padding="3,3,3,3"
|
||||
backgroundColor="#EEEEEE"
|
||||
/>
|
||||
<style id="MAIN_MENU"
|
||||
layoutWidth="FILL_PARENT"
|
||||
backgroundColor="#404040"
|
||||
/>
|
||||
<style id="MAIN_MENU_ITEM"
|
||||
padding="4,2,4,2"
|
||||
backgroundImageId="main_menu_item_background"
|
||||
textColor="#E0E0E0"
|
||||
textFlags="Parent"
|
||||
/>
|
||||
<style id="MENU_ITEM"
|
||||
padding="4,2,4,2"
|
||||
>
|
||||
<state state_focused="true" backgroundColor="#40C0C000"/>
|
||||
<state state_pressed="true" backgroundColor="#4080C000"/>
|
||||
<state state_selected="true" backgroundColor="#00F8F9Fa"/>
|
||||
<state state_hovered="true" backgroundColor="#C0FFFF00"/>
|
||||
</style>
|
||||
<style id="MENU_ICON"
|
||||
margins="2,2,2,2"
|
||||
align="Left|VCenter"
|
||||
>
|
||||
<state state_enabled="false" alpha="160"/>
|
||||
</style>
|
||||
<style id="MENU_LABEL"
|
||||
margins="4,2,4,2"
|
||||
align="Left|VCenter"
|
||||
textFlags="UnderlineHotKeys"
|
||||
>
|
||||
<state state_enabled="false" textColor="#80404040"/>
|
||||
</style>
|
||||
<style id="MAIN_MENU_LABEL"
|
||||
margins="4,2,4,2"
|
||||
align="Left|VCenter"
|
||||
textFlags="Parent"
|
||||
>
|
||||
<state state_enabled="false" textColor="#80404040"/>
|
||||
</style>
|
||||
<style id="MENU_ACCEL"
|
||||
margins="4,2,4,2"
|
||||
align="Left|VCenter"
|
||||
>
|
||||
<state state_enabled="false" textColor="#80404040"/>
|
||||
</style>
|
||||
<style id="TRANSPARENT_BUTTON_BACKGROUND"
|
||||
backgroundImageId="transparent_button_background"
|
||||
padding="4,2,4,2"
|
||||
/>
|
||||
<style id="POPUP_MENU"
|
||||
backgroundImageId="popup_menu_background_normal"
|
||||
/>
|
||||
<style id="LIST_ITEM"
|
||||
backgroundImageId="list_item_background"
|
||||
/>
|
||||
<style id="EDIT_LINE"
|
||||
backgroundImageId="editbox_background"
|
||||
padding="5,6,5,6"
|
||||
margins="2,2,2,2"
|
||||
minWidth="40"
|
||||
fontFace="Arial"
|
||||
fontFamily="SansSerif"
|
||||
fontSize="20"
|
||||
/>
|
||||
<style id="EDIT_BOX"
|
||||
backgroundImageId="editbox_background"
|
||||
padding="5,6,5,6"
|
||||
margins="2,2,2,2"
|
||||
minWidth="100"
|
||||
minHeight="60"
|
||||
layoutWidth="FILL_PARENT"
|
||||
layoutHeight="FILL_PARENT"
|
||||
fontFace="Courier New"
|
||||
fontFamily="MonoSpace"
|
||||
fontSize="20"
|
||||
/>
|
||||
|
||||
</theme>
|
||||
|
|
@ -89,18 +89,13 @@ extern (C) int UIAppMain(string[] args) {
|
|||
appendPath(exePath, "../res/mdpi/"), // when res dir is located at project directory
|
||||
appendPath(exePath, "../../res/mdpi/") // when res dir is located at the same directory as executable
|
||||
];
|
||||
// setup resource directories - will use only existing directories
|
||||
drawableCache.setResourcePaths(resourceDirs);
|
||||
// setup i18n - look for i18n directory inside one of passed directories
|
||||
i18n.findTranslationsDir(resourceDirs);
|
||||
// select translation file - for english language
|
||||
i18n.load("en.ini"); //"ru.ini", "en.ini"
|
||||
|
||||
Theme theme = loadTheme("theme_default");
|
||||
if (theme) {
|
||||
Log.d("Applying loaded theme ", theme.id);
|
||||
currentTheme = theme;
|
||||
}
|
||||
// setup resource directories - will use only existing directories
|
||||
Platform.instance.resourceDirs = resourceDirs;
|
||||
// select translation file - for english language
|
||||
Platform.instance.uiLanguage = "en";
|
||||
// load theme from file "theme_default.xml"
|
||||
Platform.instance.uiTheme = "theme_default";
|
||||
|
||||
// create window
|
||||
Window window = Platform.instance.createWindow("My Window", null);
|
||||
|
@ -142,12 +137,10 @@ extern (C) int UIAppMain(string[] args) {
|
|||
return false;
|
||||
if (item.id == 611) {
|
||||
// set interface language to english
|
||||
i18n.load("en.ini");
|
||||
contentLayout.requestLayout();
|
||||
platform.instance.uiLanguage = "en";
|
||||
} else if (item.id == 612) {
|
||||
// set interface language to russian
|
||||
i18n.load("ru.ini", "en.ini");
|
||||
contentLayout.requestLayout();
|
||||
platform.instance.uiLanguage = "ru";
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
@ -157,10 +150,24 @@ extern (C) int UIAppMain(string[] args) {
|
|||
ruLang.onMenuItemClick = onLangChange;
|
||||
langItem.add(enLang);
|
||||
langItem.add(ruLang);
|
||||
MenuItem themeItem = new MenuItem(new Action(62, "MENU_VIEW_THEME"));
|
||||
themeItem.add((new MenuItem(new Action(621, "MENU_VIEW_THEME_DEFAULT"))).type(MenuItemType.Radio).checked(true));
|
||||
themeItem.add((new MenuItem(new Action(622, "MENU_VIEW_THEME_CUSTOM1"))).type(MenuItemType.Radio));
|
||||
viewItem.add(langItem);
|
||||
MenuItem themeItem = new MenuItem(new Action(62, "MENU_VIEW_THEME"));
|
||||
MenuItem theme1 = (new MenuItem(new Action(621, "MENU_VIEW_THEME_DEFAULT"))).type(MenuItemType.Radio).checked(true);
|
||||
MenuItem theme2 = (new MenuItem(new Action(622, "MENU_VIEW_THEME_CUSTOM1"))).type(MenuItemType.Radio);
|
||||
auto onThemeChange = delegate (MenuItem item) {
|
||||
if (!item.checked)
|
||||
return false;
|
||||
if (item.id == 621) {
|
||||
platform.instance.uiTheme = "theme_default";
|
||||
} else if (item.id == 622) {
|
||||
platform.instance.uiTheme = "theme_custom1";
|
||||
}
|
||||
return true;
|
||||
};
|
||||
theme1.onMenuItemClick = onThemeChange;
|
||||
theme2.onMenuItemClick = onThemeChange;
|
||||
themeItem.add(theme1);
|
||||
themeItem.add(theme2);
|
||||
viewItem.add(themeItem);
|
||||
|
||||
MenuItem windowItem = new MenuItem(new Action(3, "MENU_WINDOW"c));
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<theme id="theme_default" >
|
||||
<theme id="theme_default" fontSize="15" >
|
||||
<style id="BUTTON"
|
||||
backgroundImageId="btn_default_small"
|
||||
align="Center"
|
||||
|
@ -62,7 +62,6 @@
|
|||
</style>
|
||||
<style id="TAB_UP_BUTTON_TEXT"
|
||||
textColor="#000000"
|
||||
backgroundImageId="tab_up_background"
|
||||
fontSize="12"
|
||||
align="Center"
|
||||
>
|
||||
|
|
|
@ -28,7 +28,12 @@ import dlangui.widgets.popup;
|
|||
import dlangui.graphics.drawbuf;
|
||||
|
||||
private import dlangui.graphics.gldrawbuf;
|
||||
private import std.algorithm;
|
||||
|
||||
/**
|
||||
* Window abstraction layer. Widgets can be shown only inside window.
|
||||
*
|
||||
*/
|
||||
class Window {
|
||||
protected int _dx;
|
||||
protected int _dy;
|
||||
|
@ -49,8 +54,17 @@ class Window {
|
|||
_mainWidget.window = this;
|
||||
}
|
||||
abstract void show();
|
||||
/// returns window caption
|
||||
abstract @property string windowCaption();
|
||||
/// sets window caption
|
||||
abstract @property void windowCaption(string caption);
|
||||
/// requests layout for main widget and popups
|
||||
void requestLayout() {
|
||||
if (_mainWidget)
|
||||
_mainWidget.requestLayout();
|
||||
foreach(p; _popups)
|
||||
p.requestLayout();
|
||||
}
|
||||
void measure() {
|
||||
if (_mainWidget !is null) {
|
||||
_mainWidget.measure(_dx, _dy);
|
||||
|
@ -524,6 +538,14 @@ class Window {
|
|||
abstract void invalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Platform abstraction layer.
|
||||
*
|
||||
* Represents application.
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
class Platform {
|
||||
static __gshared Platform _instance;
|
||||
static void setInstance(Platform instance) {
|
||||
|
@ -540,6 +562,60 @@ class Platform {
|
|||
abstract dstring getClipboardText(bool mouseBuffer = false);
|
||||
/// sets text to clipboard (when mouseBuffer == true, use mouse selection clipboard - under linux)
|
||||
abstract void setClipboardText(dstring text, bool mouseBuffer = false);
|
||||
|
||||
/// calls request layout for all windows
|
||||
abstract void requestLayout();
|
||||
|
||||
protected string _uiLanguage;
|
||||
/// returns currently selected UI language code
|
||||
@property string uiLanguage() {
|
||||
return _uiLanguage;
|
||||
}
|
||||
/// set UI language (e.g. "en", "fr", "ru")
|
||||
@property Platform uiLanguage(string langCode) {
|
||||
if (_uiLanguage.equal(langCode))
|
||||
return this;
|
||||
_uiLanguage = langCode;
|
||||
if (langCode.equal("en"))
|
||||
i18n.load("en.ini"); //"ru.ini", "en.ini"
|
||||
else
|
||||
i18n.load(langCode ~ ".ini", "en.ini");
|
||||
requestLayout();
|
||||
return this;
|
||||
}
|
||||
protected string _themeId;
|
||||
@property string uiTheme() {
|
||||
return _themeId;
|
||||
}
|
||||
/// sets application UI theme
|
||||
@property Platform uiTheme(string themeResourceId) {
|
||||
if (_themeId.equal(themeResourceId))
|
||||
return this;
|
||||
_themeId = themeResourceId;
|
||||
Theme theme = loadTheme(themeResourceId);
|
||||
if (!theme) {
|
||||
Log.e("Cannot load theme from resource ", themeResourceId, " - will use default theme");
|
||||
theme = createDefaultTheme();
|
||||
} else {
|
||||
Log.i("Applying loaded theme ", theme.id);
|
||||
}
|
||||
currentTheme = theme;
|
||||
requestLayout();
|
||||
return this;
|
||||
}
|
||||
|
||||
protected string[] _resourceDirs;
|
||||
/// returns list of resource directories
|
||||
@property string[] resourceDirs() { return _resourceDirs; }
|
||||
/// set list of directories to load resources from
|
||||
@property Platform resourceDirs(string[] dirs) {
|
||||
// setup resource directories - will use only existing directories
|
||||
drawableCache.setResourcePaths(dirs);
|
||||
_resourceDirs = drawableCache.resourcePaths;
|
||||
// setup i18n - look for i18n directory inside one of passed directories
|
||||
i18n.findTranslationsDir(dirs);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/// get current platform object instance
|
||||
|
|
|
@ -662,6 +662,15 @@ version(USE_SDL) {
|
|||
return null;
|
||||
}
|
||||
|
||||
/// calls request layout for all windows
|
||||
override void requestLayout() {
|
||||
foreach(w; _windowMap) {
|
||||
w.requestLayout();
|
||||
w.invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private uint _redrawEventId;
|
||||
|
||||
void sendRedrawEvent(uint windowId, uint code) {
|
||||
|
|
|
@ -976,7 +976,7 @@ bool loadStyleAttributes(Style style, Element elem, bool allowStates) {
|
|||
if ("fontFamily" in elem.tag.attr)
|
||||
style.fontFamily = decodeFontFamily(elem.tag.attr["fontFamily"]);
|
||||
if ("fontSize" in elem.tag.attr)
|
||||
style.fontSize = cast(ushort)decodeDimension(elem.tag.attr["fontFace"]);
|
||||
style.fontSize = cast(ushort)decodeDimension(elem.tag.attr["fontSize"]);
|
||||
if ("layoutWidth" in elem.tag.attr)
|
||||
style.layoutWidth = decodeLayoutDimension(elem.tag.attr["layoutWidth"]);
|
||||
if ("layoutHeight" in elem.tag.attr)
|
||||
|
@ -1021,7 +1021,7 @@ bool loadStyleAttributes(Style style, Element elem, bool allowStates) {
|
|||
*
|
||||
*/
|
||||
bool loadTheme(Theme theme, Element doc, int level = 0) {
|
||||
if (doc.tag.name.equal("theme")) {
|
||||
if (!doc.tag.name.equal("theme")) {
|
||||
Log.e("<theme> element should be main in theme file!");
|
||||
return false;
|
||||
}
|
||||
|
@ -1040,11 +1040,10 @@ bool loadTheme(Theme theme, Element doc, int level = 0) {
|
|||
// load <style>
|
||||
string styleid = attrValue(styleitem, "id");
|
||||
string styleparent = attrValue(styleitem, "parent");
|
||||
if (styleid !is null) {
|
||||
if (styleid.length) {
|
||||
// create new style
|
||||
Style parentStyle = null;
|
||||
if (styleparent !is null)
|
||||
parentStyle = theme.get(styleparent);
|
||||
parentStyle = theme.get(styleparent);
|
||||
Style style = parentStyle.createSubstyle(styleid);
|
||||
loadStyleAttributes(style, styleitem, true);
|
||||
} else {
|
||||
|
@ -1079,7 +1078,7 @@ bool loadTheme(Theme theme, string resourceId, int level = 0) {
|
|||
Log.e("Invalid XML resource ", resourceId);
|
||||
return false;
|
||||
} catch (Throwable e) {
|
||||
Log.e("Cannot read drawable resource ", resourceId, " from file ", filename);
|
||||
Log.e("Cannot read XML resource ", resourceId, " from file ", filename, " exception: ", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue