1 module fluid.default_theme;
2 
3 import fluid.node;
4 import fluid.frame;
5 import fluid.style;
6 import fluid.button;
7 import fluid.slider;
8 import fluid.backend;
9 import fluid.checkbox;
10 import fluid.radiobox;
11 import fluid.typeface;
12 import fluid.drag_slot;
13 import fluid.separator;
14 import fluid.file_input;
15 import fluid.text_input;
16 import fluid.popup_frame;
17 import fluid.number_input;
18 import fluid.scroll_input;
19 
20 /// Theme with no properties set.
21 ///
22 /// Unlike `Theme.init` or `null`, which will be replaced by fluidDefaultTheme or the parent's theme, this can be used as
23 /// a valid theme for any node. This makes it useful for automatic tests, since it has guaranteed no margins, padding,
24 /// or other properties that may confuse the tester.
25 Theme nullTheme;
26 
27 /// Default theme that Fluid will use if no theme is supplied. It is a very simple theme that does the minimum to make
28 /// the role of each node understandable.
29 Theme fluidDefaultTheme;
30 
31 static this() {
32 
33     Image loadBWImage(string filename)(int width, int height) @trusted {
34 
35         import std.array;
36         import std.format;
37         import std.algorithm;
38 
39         const area = width * height;
40 
41         auto file = cast(ubyte[]) import(filename);
42         auto data = file.map!(a => Color(0, 0, 0, a)).array;
43 
44         assert(data.length == area, format!"Wrong %s area %s, expected %s"(filename, data.length, area));
45 
46         // TODO use Format.alpha
47         return Image(data, width, height);
48 
49     }
50 
51     with (Rule) {
52 
53         nullTheme.add(
54             rule!Node(),
55         );
56 
57         fluidDefaultTheme.add(
58             rule!Node(
59                 typeface = Typeface.defaultTypeface,
60                 textColor = color("#000"),
61                 selectionBackgroundColor = color("#55b9ff"),
62             ),
63             rule!Frame(
64                 backgroundColor = color("#fff"),
65             ),
66             rule!Button(
67                 backgroundColor = color("#dadada"),
68                 mouseCursor = FluidMouseCursor.pointer,
69                 margin.sideY = 2,
70                 padding.sideX = 6,
71 
72                 when!"a.isHovered"(backgroundColor = color("#ccc")),
73                 when!"a.isFocused"(backgroundColor = color("#ddd")),  // TODO use an outline for focus
74                 when!"a.isPressed"(backgroundColor = color("#aaa")),
75                 when!"a.isDisabled"(
76                     textColor = color("000a"),
77                     backgroundColor = color("eee5"),
78                     // TODO disabled should apply opacity, and should work for every node
79                 ),
80             ),
81             rule!FrameButton(
82                 mouseCursor = FluidMouseCursor.pointer,
83             ),
84             rule!TextInput(
85                 backgroundColor = color("#fff"),
86                 borderStyle = colorBorder(color("#aaa")),
87                 mouseCursor = FluidMouseCursor.text,
88 
89                 margin.sideY = 2,
90                 padding.sideX = 6,
91                 border.sideBottom = 2,
92 
93                 when!"a.isEmpty"(textColor = color("#000a")),
94                 when!"a.isFocused"(borderStyle = colorBorder(color("#555")))
95                     .otherwise(selectionBackgroundColor = color("#ccc")),
96                 when!"a.isDisabled"(
97                     textColor = color("#000a"),
98                     backgroundColor = color("#fff5"),
99                 ),
100             ),
101             rule!NumberInputSpinner(
102                 mouseCursor = FluidMouseCursor.pointer,
103                 extra = new NumberInputSpinner.Extra(loadBWImage!"arrows-alpha"(40, 64)),
104             ),
105             rule!AbstractSlider(
106                 backgroundColor = color("#ddd"),
107                 lineColor = color("#ddd"),
108             ),
109             rule!SliderHandle(
110                 backgroundColor = color("#aaa"),
111             ),
112             rule!ScrollInput(
113                 backgroundColor = color("#eee"),
114             ),
115             rule!ScrollInputHandle(
116                 backgroundColor = color("#aaa"),
117 
118                 when!"a.isHovered"(backgroundColor = color("#888")),
119                 when!"a.isFocused"(backgroundColor = color("#777")),
120                 when!"a.isPressed"(backgroundColor = color("#555")),
121                 when!"a.isDisabled"(backgroundColor = color("#aaa5")),
122             ),
123             rule!PopupFrame(
124                 border = 1,
125                 borderStyle = colorBorder(color("#555a")),
126                 children!Button(
127                     backgroundColor = Color.init,
128                     margin = 0,
129                 ),
130             ),
131             /*rule!FileInputSuggestion(
132                 margin = 0,
133                 backgroundColor = color("#fff"),
134                 when!"a.isSelected"(backgroundColor = color("#55b9ff"))
135             ),*/
136             rule!Checkbox(
137                 margin.sideX = 8,
138                 margin.sideY = 4,
139                 border = 1,
140                 padding = 1,
141                 borderStyle = colorBorder(color("#555")),
142                 mouseCursor = FluidMouseCursor.pointer,
143 
144                 when!"a.isFocused"(backgroundColor = color("#ddd")),
145                 when!"a.isChecked"(
146                     extra = new Checkbox.Extra(loadBWImage!"checkmark-alpha"(64, 50)),
147                 ),
148             ),
149             rule!Radiobox(
150                 margin.sideX = 8,
151                 margin.sideY = 4,
152                 border = 0,
153                 borderStyle = null,
154                 padding = 2,
155                 extra = new Radiobox.Extra(1, color("#555"), color("#5550")),
156 
157                 when!"a.isFocused"(backgroundColor = color("#ddd")),
158                 when!"a.isChecked"(
159                     extra = new Radiobox.Extra(1, color("#555"), color("#000"))
160                 ),
161             ),
162             rule!Separator(
163                 padding = 4,
164                 lineColor = color("#ccc"),
165             ),
166             rule!DragSlot(
167                 padding.sideX = 6,
168                 padding.sideY = 0,
169                 border = 1,
170                 borderStyle = colorBorder(color("#555a")),
171                 backgroundColor = color("#fff"),
172                 margin = 4,  // for testing
173             ),
174             rule!DragHandle(
175                 lineColor = color("#ccc"),
176                 padding.sideX = 8,
177                 padding.sideY = 6,
178                 extra = new DragHandle.Extra(5),
179             ),
180         );
181 
182     }
183 
184 }