1 /**
2 Grimoire
3 Copyright (c) 2017 Enalye
4 
5 This software is provided 'as-is', without any express or implied warranty.
6 In no event will the authors be held liable for any damages arising
7 from the use of this software.
8 
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute
11 it freely, subject to the following restrictions:
12 
13 	1. The origin of this software must not be misrepresented;
14 	   you must not claim that you wrote the original software.
15 	   If you use this software in a product, an acknowledgment
16 	   in the product documentation would be appreciated but
17 	   is not required.
18 
19 	2. Altered source versions must be plainly marked as such,
20 	   and must not be misrepresented as being the original software.
21 
22 	3. This notice may not be removed or altered from any source distribution.
23 */
24 
25 module ui.colorpicker;
26 
27 import core.all;
28 import render.all;
29 import common.all;
30 
31 import ui.all;
32 
33 class ColorViewer: Widget {
34 	Color color;
35 
36 	this() {}
37 
38 	override void onEvent(Event event) {}
39 	override void update(float deltaTime) {}
40 	override void draw() {
41 		drawFilledRect(_position - _size / 2f, _size, color);
42 	}
43 }
44 
45 class ColorPicker: ModalWindow {
46 	private {
47 		DropDownList _blendList;
48 		Slider _redSlider, _blueSlider, _greenSlider, _alphaSlider;
49 		ColorViewer _viewer;
50 	}
51 
52 	@property {
53 		Color color() const {
54 			return Color(_redSlider.value01, _blueSlider.value01,
55 				_greenSlider.value01, _alphaSlider.value01);
56 		}
57 
58 		Blend blend() const {
59 			switch(_blendList.selected) {
60 			case 0:
61 				return Blend.AlphaBlending;
62 			case 1:
63 				return Blend.AdditiveBlending;
64 			case 2:
65 				return Blend.ModularBlending;
66 			case 3:
67 				return Blend.NoBlending;
68 			default:
69 				throw new Exception("Invalid kind of blending");
70 			}
71 		}
72 	}
73 
74 	this(Color newColor = Color.white, Blend newBlend = Blend.AlphaBlending) {
75 		Slider makeSlider(VContainer container, string title) {
76 			auto slider = new HSlider;
77 			slider.min = 0;
78 			slider.min = 255;
79 			slider.step = 255;
80 			slider.size = Vec2f(255f, 10f);
81 
82 			auto hc = new HContainer;
83 			hc.spacing = Vec2f(10f, 0f);
84 			hc.addChild(new Label(title));
85 			hc.addChild(slider);
86 			container.addChild(hc);
87 			return slider;
88 		}
89 
90 		auto container = new VContainer;
91 		container.spacing = Vec2f(0f, 10f);
92 		_redSlider = makeSlider(container, "R");
93 		_blueSlider = makeSlider(container, "G");
94 		_greenSlider = makeSlider(container, "B");
95 		_alphaSlider = makeSlider(container, "A");
96 
97 		_blendList = new DropDownList(Vec2f(200f, 25f), 4U);
98 		foreach(mode; [
99 			"Alpha Blending", "Additive Blending",
100 			"Modular Blending", "No Blending"])
101 			_blendList.addChild(new TextButton(mode));
102 		container.addChild(_blendList);
103 
104 		_redSlider.value01 = newColor.r;
105 		_blueSlider.value01 = newColor.g;
106 		_greenSlider.value01 = newColor.b;
107 		_alphaSlider.value01 = newColor.a;
108 
109 		_viewer = new ColorViewer;
110 		_viewer.size = Vec2f(100f, 100f);
111 
112 		auto hc2 = new HContainer;
113 		hc2.spacing = Vec2f(20f, 5f);
114 		hc2.addChild(container);
115 		hc2.addChild(_viewer);
116 
117 		super("Couleur", hc2.size);
118 		layout.addChild(hc2);
119 
120 		switch(newBlend) with(Blend) {
121 		case AlphaBlending:
122 			_blendList.selected = 0U;
123 			break;
124 		case AdditiveBlending:
125 			_blendList.selected = 1U;
126 			break;
127 		case ModularBlending:
128 			_blendList.selected = 2U;
129 			break;
130 		case NoBlending:
131 			_blendList.selected = 3U;
132 			break;
133 		default:
134 			_blendList.selected = 0U;
135 		}
136 	}
137 
138 	override void update(float deltaTime) {
139 		super.update(deltaTime);
140 		_viewer.color = color();
141 	}
142 }