@@ -543,13 +543,11 @@ copyright-holders:m1macrophage
543
543
function()
544
544
local id_port_index <const> = string.len("slider_knob_") + 1
545
545
546
- -- Local state used by the pointer update handler.
547
- local sliders = {}
548
- local slider_knobs = {}
549
- local slider_fields = {}
550
- local selected = 0
546
+ -- State used by pointer handlers.
547
+ local sliders = {} -- Info about all sliders (constant after initialization).
548
+ local pointers = {} -- Pointer tracking state.
551
549
552
- -- Gather relevant elements and inputs into local state .
550
+ -- Gather relevant elements and inputs into `sliders` .
553
551
local view = file.views["Default Layout"]
554
552
for i = 1, #view.items do
555
553
local item = view.items:at(i)
@@ -575,50 +573,88 @@ copyright-holders:m1macrophage
575
573
print("LAYOUT ERROR - Element: 'slider_" .. slider_id .. "' does not exist.")
576
574
end
577
575
578
- table.insert(sliders, slider)
579
- table.insert(slider_knobs, item)
580
- table.insert(slider_fields, field)
576
+ local slider_info = {}
577
+ slider_info.slider = slider
578
+ slider_info.knob = item
579
+ slider_info.field = field
580
+ table.insert(sliders, slider_info)
581
581
end
582
582
end
583
583
584
- view:set_pointer_updated_callback(
585
- function(type, id, dev, x, y, btn, dn, up, cnt)
586
- -- No button pressed. Reset state.
587
- if btn & 1 == 0 then
588
- selected = 0
589
- return
590
- end
584
+ local function forget_pointers()
585
+ pointers = {}
586
+ end
587
+
588
+ local function pointer_lost(type, id, dev, x, y, up, cnt)
589
+ pointers[id] = nil
590
+ end
591
591
592
- -- Button just pressed. Find affected slider.
593
- if dn & 1 ~= 0 then
594
- for i = 1, #sliders do
595
- if sliders[i].bounds:includes(x, y) then
596
- selected = i
597
- break
598
- end
592
+ local function pointer_updated(type, id, dev, x, y, btn, dn, up, cnt)
593
+ -- Button not pressed? Reset state of current pointer.
594
+ if btn & 1 == 0 then
595
+ pointers[id] = nil
596
+ return
597
+ end
598
+
599
+ -- Button just pressed? Find affected slider, if any.
600
+ if dn & 1 ~= 0 then
601
+ for i = 1, #sliders do
602
+ if sliders[i].knob.bounds:includes(x, y) then
603
+ local pointer = {}
604
+ pointer.selected_slider = i
605
+ pointer.relative = true
606
+ pointer.start_y = y
607
+ pointer.start_value = sliders[i].field.user_value
608
+ pointers[id] = pointer
609
+ break
610
+ elseif sliders[i].slider.bounds:includes(x, y) then
611
+ local pointer = {}
612
+ pointer.selected_slider = i
613
+ pointer.relative = false
614
+ pointers[id] = pointer
615
+ break
599
616
end
600
617
end
618
+ end
601
619
602
- -- No slider selected. Nothing to do.
603
- if selected <= 0 then
604
- return
605
- end
620
+ -- No slider selected by current pointer? Nothing to do.
621
+ if pointers[id] == nil then
622
+ return
623
+ end
624
+
625
+ -- A slider is selected. Update state and, indirectly,
626
+ -- slider knob position, based on the pointer's Y position.
627
+ -- It is assumed the attached IO field is an IPT_ADJUSTER
628
+ -- with a range of 0-100 (the default).
629
+
630
+ local pointer = pointers[id]
631
+ local slider_info = sliders[pointer.selected_slider]
632
+
633
+ local knob_half_height = slider_info.knob.bounds.height / 2
634
+ local min_y = slider_info.slider.bounds.y0 + knob_half_height
635
+ local max_y = slider_info.slider.bounds.y1 - knob_half_height
636
+
637
+ local new_value = 0
638
+ if pointer.relative then
639
+ -- User clicked on the knob. New value depends on how
640
+ -- much the knob was dragged.
641
+ new_value = pointer.start_value - 100 * (y - pointer.start_y) / (max_y - min_y)
642
+ else
643
+ -- User clicked elsewhere on the slider. New value
644
+ -- depends on the absolute position of the click.
645
+ new_value = 100 - 100 * (y - min_y) / (max_y - min_y)
646
+ end
647
+
648
+ new_value = math.floor(new_value + 0.5)
649
+ if new_value < 0 then new_value = 0 end
650
+ if new_value > 100 then new_value = 100 end
651
+ slider_info.field.user_value = new_value
652
+ end
606
653
607
- -- A slider is selected. Update state and, indirectly,
608
- -- slider knob position, based on the pointer's Y position.
609
- -- It is assumed the attached IO field is an IPT_ADJUSTER
610
- -- with a range of 0-100 (the default).
611
-
612
- local knob_half_height = slider_knobs[selected].bounds.height / 2
613
- local min_y = sliders[selected].bounds.y0 + knob_half_height
614
- local max_y = sliders[selected].bounds.y1 - knob_half_height
615
-
616
- local new_value = 100 - 100 * (y - min_y) / (max_y - min_y)
617
- new_value = math.floor(new_value + 0.5)
618
- if new_value < 0 then new_value = 0 end
619
- if new_value > 100 then new_value = 100 end
620
- slider_fields[selected].user_value = new_value
621
- end)
654
+ view:set_pointer_updated_callback(pointer_updated)
655
+ view:set_pointer_left_callback(pointer_lost)
656
+ view:set_pointer_aborted_callback(pointer_lost)
657
+ view:set_forget_pointers_callback(forget_pointers)
622
658
end)
623
659
]]> </script >
624
660
</mamelayout >
0 commit comments