Skip to content

Commit 7464d2a

Browse files
polluxsynthfundamental
authored andcommitted
Button: Add rocker mode
Rocker mode brings up two side-by-side buttons instead of one, like a rocker or two button radio button. When one side is active the other is not. This is intended for boolean parameters that have two values whose counterparts are not necessarily obvious, such as linear vs. exponential mode for the amp envs. For these parameters, the label property needs to contain the two values to be shown, separated by a / , e.g. "lin/log". The left value corresponds to the 'true' value of the boolean; the right value corresponds to the 'false' value
1 parent fd6a1f8 commit 7464d2a

File tree

1 file changed

+89
-10
lines changed

1 file changed

+89
-10
lines changed

src/mruby-zest/qml/Button.qml

Lines changed: 89 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Widget {
77
property Function whenValue: nil;
88
property Float pad: 1.0/64
99
property Bool active: true
10+
property Bool rocker: false
1011

1112
function onMousePress(ev) {
1213
return if !self.active
@@ -66,6 +67,14 @@ Widget {
6667
text_color2 = Theme::TextColor
6768
vg.font_face("bold")
6869
vg.font_size h*self.textScale
70+
if(button.rocker)
71+
# Expects label to be of the form "lin/log", where the left
72+
# portion represents the 'true' value of the underlying parameter.
73+
texts = label.split("/")
74+
text = texts[0]
75+
else
76+
text = label
77+
end
6978
# While it initially looks redundant to test against 'true', remember
7079
# that 'value' is a float when the Button is a TriggerButton. If we
7180
# don't check against true here, the button text while change to the
@@ -78,10 +87,34 @@ Widget {
7887
end
7988
if(layoutOpts.include? :left_text)
8089
vg.text_align NVG::ALIGN_LEFT | NVG::ALIGN_MIDDLE
81-
vg.text(8,h/2,button.label.upcase)
90+
vg.text(8,h/2,text.upcase)
8291
else
8392
vg.text_align NVG::ALIGN_CENTER | NVG::ALIGN_MIDDLE
84-
vg.text(w/2,h/2,button.label.upcase)
93+
if(button.rocker)
94+
vg.text(w/4,h/2,text.upcase)
95+
else
96+
vg.text(w/2,h/2,text.upcase)
97+
end
98+
end
99+
if (button.rocker)
100+
# Right hand side of rocker button
101+
# We use -1 so we always get the last element regardless of if
102+
# the array actually contains 2 elements
103+
text = texts[-1]
104+
if(value == true)
105+
vg.fill_color(text_color2)
106+
else
107+
vg.fill_color(text_color1)
108+
end
109+
if(layoutOpts.include? :left_text)
110+
# Since the left button half aligns left, we align the
111+
# right hand one to the right, for symmetry.
112+
vg.text_align NVG::ALIGN_RIGHT | NVG::ALIGN_MIDDLE
113+
vg.text(w-9,h/2,text.upcase)
114+
else
115+
vg.text_align NVG::ALIGN_CENTER | NVG::ALIGN_MIDDLE
116+
vg.text(w*3/4-2,h/2,text.upcase)
117+
end
85118
end
86119
}
87120
@@ -103,7 +136,13 @@ Widget {
103136
on_color = Theme::ButtonActive
104137
cs = 0
105138
vg.path do |v|
106-
v.rounded_rect(w*pad, h*pad, w*(1-2*pad), h*(1-2*pad), 2)
139+
# Whole button, or left part of button for rocker
140+
if(button.rocker)
141+
r = w*(1-2*pad)*0.5
142+
else
143+
r = w*(1-2*pad)
144+
end
145+
v.rounded_rect(w*pad, h*pad, r, h*(1-2*pad), 2)
107146
# Although the test against 'true' might seem redundant, it's
108147
# needed because 'value' will be a float when the Button is a
109148
# TriggerButton, and we purposely want to check for a boolean
@@ -127,22 +166,62 @@ Widget {
127166
v.fill
128167
v.stroke_width 1
129168
v.stroke
169+
end
130170

171+
if(button.rocker)
172+
# Right part of rocker button
173+
vg.path do |v|
174+
v.rounded_rect(w*(1-2*pad)*0.5, h*pad, w*(1-2*pad)*0.5, h*(1-2*pad), 2)
175+
# Rocker buttons are never used as TriggerButtons, so can
176+
# always assume 'value' is a boolean value here.
177+
if(button.value)
178+
paint = v.linear_gradient(0,0,0,h,
179+
Theme::ButtonGrad1, Theme::ButtonGrad2)
180+
v.fill_paint paint
181+
else
182+
v.fill_color on_color
183+
end
184+
v.fill
185+
v.stroke_width 1
186+
v.stroke
187+
end
131188
end
132189

133190
vg.path do |v|
191+
# Little, slightly lighter horizontal field at top of button
134192
hh = h/20
135-
v.move_to(w*pad+1, h*pad+hh)
136-
v.line_to(w*(1-2*pad)+1, h*pad+hh)
137-
if(cs == 0)
138-
v.stroke_color color("5c5c5c")
139-
elsif(cs == 1)
140-
v.stroke_color color("16a39c")
141-
end
142193
if([0,1].include?(cs))
194+
if(button.rocker)
195+
r = w*(1-2*pad)*0.5-1
196+
else
197+
r = w*(1-2*pad)+1
198+
end
143199
v.stroke_width hh
200+
201+
v.move_to(w*pad+1, h*pad+hh)
202+
v.line_to(r, h*pad+hh)
203+
if(cs == 0)
204+
v.stroke_color color("5c5c5c")
205+
elsif(cs == 1)
206+
v.stroke_color color("16a39c")
207+
end
144208
v.stroke
209+
210+
if(button.rocker)
211+
# Right part in rocker mode
212+
vg.path do |v|
213+
v.move_to(w*(1-2*pad)*0.5+1, h*pad+hh)
214+
v.line_to(w*(1-2*pad)-1, h*pad+hh)
215+
if(cs == 1)
216+
v.stroke_color color("5c5c5c")
217+
elsif(cs == 0)
218+
v.stroke_color color("16a39c")
219+
end
220+
v.stroke
221+
end
222+
end
145223
end
224+
146225
end
147226
}
148227

0 commit comments

Comments
 (0)