1 /**
2 * Film-strip on/off switch.
3 * Copyright: Copyright Cut Through Recordings 2017
4 * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
5 * Authors:   Ethan Reker
6 */
7 module dplug.flatwidgets.flatswitch;
8 
9 import std.math;
10 import dplug.core.math;
11 import dplug.graphics.drawex;
12 import dplug.gui.element;
13 import dplug.client.params;
14 
15 class UIImageSwitch : UIElement, IParameterListener
16 {
17 public:
18 nothrow:
19 @nogc:
20 
21     enum Orientation
22     {
23         vertical,
24         horizontal
25     }
26 
27     Orientation orientation = Orientation.vertical;
28 
29     this(UIContext context, BoolParameter param, OwnedImage!RGBA onImage, OwnedImage!RGBA offImage)
30     {
31         super(context);
32         _param = param;
33         _param.addListener(this);
34 
35         _onImage = onImage;
36         _offImage = offImage;
37         assert(_onImage.h == _offImage.h);
38         assert(_onImage.w == _offImage.w);
39         _width = _onImage.w;
40         _height = _onImage.h;
41 
42     }
43 
44     ~this()
45     {
46         _param.removeListener(this);
47     }
48 
49     bool getState(){
50       return unsafeObjectCast!BoolParameter(_param).valueAtomic();
51     }
52 
53     override void onDraw(ImageRef!RGBA diffuseMap, ImageRef!L16 depthMap, ImageRef!RGBA materialMap, box2i[] dirtyRects) nothrow @nogc
54     {
55           auto _currentImage = getState() ? _onImage : _offImage;
56           foreach(dirtyRect; dirtyRects){
57 
58               auto croppedDiffuseIn = _currentImage.crop(dirtyRect);
59               auto croppedDiffuseOut = diffuseMap.crop(dirtyRect);
60 
61               int w = dirtyRect.width;
62               int h = dirtyRect.height;
63 
64               for(int j = 0; j < h; ++j){
65 
66                   RGBA[] input = croppedDiffuseIn.scanline(j);
67                   RGBA[] output = croppedDiffuseOut.scanline(j);
68 
69 
70                   for(int i = 0; i < w; ++i){
71                       ubyte alpha = input[i].a;
72 
73                       RGBA color = RGBA.op!q{.blend(a, b, c)} (input[i], output[i], alpha);
74                       output[i] = color;
75                   }
76               }
77 
78           }
79     }
80 
81     override bool onMouseClick(int x, int y, int button, bool isDoubleClick, MouseState mstate)
82     {
83         // double-click => set to default
84         _param.beginParamEdit();
85         _param.setFromGUI(!_param.value());
86         _param.endParamEdit();
87         return true;
88     }
89 
90     override void onMouseEnter()
91     {
92         setDirtyWhole();
93     }
94 
95     override void onMouseMove(int x, int y, int dx, int dy, MouseState mstate)
96     {
97         
98     }
99 
100     override void onMouseExit()
101     {
102         setDirtyWhole();
103     }
104 
105     override void onBeginDrag()
106     {
107 
108     }
109 
110     override void onStopDrag()
111     {
112 
113     }
114     
115     override void onMouseDrag(int x, int y, int dx, int dy, MouseState mstate)
116     {
117 
118         
119     }
120 
121     override void onParameterChanged(Parameter sender) nothrow @nogc
122     {
123         setDirtyWhole();
124     }
125 
126     override void onBeginParameterEdit(Parameter sender)
127     {
128     }
129 
130     override void onEndParameterEdit(Parameter sender)
131     {
132     }
133 
134 protected:
135 
136     BoolParameter _param;
137     bool _state;
138     OwnedImage!RGBA _onImage;
139     OwnedImage!RGBA _offImage;
140     int _width;
141     int _height;
142 }