1 module rpui.theme;
2 
3 import std.path;
4 import std.file;
5 
6 import rpdl;
7 
8 import gapi.font;
9 import gapi.texture;
10 import gapi.shader;
11 
12 import rpui.paths;
13 
14 struct Theme {
15     string name;
16     RpdlTree tree;
17     Texture2D skin;
18     Font regularFont;
19     int regularFontSize;
20     ThemeShaders shaders;
21 }
22 
23 struct ThemeShaders {
24     ShaderProgram textureAtlasShader;
25     ShaderProgram textShader;
26     ShaderProgram transformShader;
27     ShaderProgram colorShader;
28 }
29 
30 Theme createThemeByName(in string theme) {
31     const paths = createPathes();
32     const dir = buildPath(paths.resources, "ui", "themes", theme);
33 
34     auto tree = new RpdlTree(dir);
35     tree.load("theme.rdl");
36 
37     const skinPath = buildPath(dir, "controls.png");
38     const skin = createTexture2DFromFile(skinPath);
39 
40     const regularFontFileName = tree.data.getString("General.regularFont.0");
41     const regularFontSize = tree.data.getInteger("General.regularFont.1");
42     Font font = createFontFromFile(buildPath(paths.resources, "fonts", regularFontFileName));
43 
44     return Theme(theme, tree, skin, font, regularFontSize, createThemeShaders());
45 }
46 
47 private ThemeShaders createThemeShaders() {
48     return ThemeShaders(
49         createSimpleShader("tex atlas", "transform_vertex.glsl", "texture_atlas_fragment.glsl"),
50         createSimpleShader("text", "transform_vertex.glsl", "text_fragment.glsl"),
51         createSimpleShader("transform", "transform_vertex.glsl", "texture_fragment.glsl"),
52         createSimpleShader("color", "transform_vertex.glsl", "color_fragment.glsl"),
53     );
54 }
55 
56 private ShaderProgram createSimpleShader(in string name, in string vertex, in string fragment) {
57     const vertexSource = readText(buildPath("res", "shaders", vertex));
58     const vertexShader = createShader(vertex, ShaderType.vertex, vertexSource);
59 
60     const fragmentSource = readText(buildPath("res", "shaders", fragment));
61     const fragmentShader = createShader(fragment, ShaderType.fragment, fragmentSource);
62 
63     return createShaderProgram(name ~ " shader program", [vertexShader, fragmentShader]);
64 }