Here is a prototype that combines Helgef's multi-breakpoint code with a custom UI which allows adding/removing of breakpoints
Basically in order to save this "Setting", we use a hidden GuiControl containing a text string.
Any time you change the settings, the string is changed and gets stored in UCRs ini file.
So here is a test script that shows the text string that will be saved/loaded, plus a slider so you can simulate various input values.
If we can get this code behaving right, then this should basically cater for all scenarios
Code: Select all
#SingleInstance force
sc := new SegmentControl(Func("GuiControlCallback"))
setting := "0,0|60,80|100,100"
Gui, Add, Text, xm y+10, Hidden Settings Control
Gui, Add, Edit, w125 xm y+5 hwndhSettingsEdit, % setting
Gui, Add, Text, xm y+5, Input Simulation
Gui, Add, Slider, xm w125 y+5 gInputSliderChanged vSliderValue
sc.LoadSettings(setting)
Gui, Show, x0 y0
return
GuiClose:
ExitApp
InputSliderChanged:
Gui, Submit, NoHide
ToolTip % SliderValue " = " sc.f(SliderValue)
return
GuiControlCallback(value){
global hSettingsEdit
GuiControl, , % hSettingsEdit, % value
}
class SegmentControl {
Segments := []
Points := []
__New(callback, options := ""){
this.callback := callback
Gui, Add, ListView, hwndhwnd w100 h100, Lower|Upper
this.hLV := hwnd
Gui, Add, Button, hwndhwnd x+5 yp w20 h100, -
fn := this.DeleteClicked.Bind(this)
GuiControl, +g, % hwnd, % fn
Gui, Add, Edit, xm y+5 hwndhwnd w45
this.hEditLow := hwnd
Gui, Add, Edit, x+10 yp hwndhwnd w45
this.hEditHigh := hwnd
Gui, Add, Button, hwndhwnd x+5 yp w20, +
fn := this.AddClicked.Bind(this)
GuiControl, +g, % hwnd, % fn
}
AddPoint(x, y, save := true){
this.Points.push([x, y])
this.BuildSegments()
if (save){
this.SaveSettings()
}
}
LoadSettings(str){
chunks := StrSplit(str, "|")
for i, pt in chunks {
p := StrSplit(pt, ",")
this.AddPoint(p[1], p[2], false)
}
}
SaveSettings(){
str := ""
for i, chunk in this.Points {
if (i > 1){
str .= "|"
}
str .= chunk[1] "," chunk[2]
}
this.callback.Call(str)
}
BuildSegments(){
Gui, ListView, % hLV
LV_Delete()
for i, p in this.Points {
LV_Add(, p[1], p[2])
}
pts := this.Points.clone()
p0 := pts.removeat(1)
this.Segments := []
for i, p1 in pts {
this.Segments.push( {k : (p1.2-p0.2) / (p1.1-p0.1) , m : ( p1.1*p0.2 - p0.1*p1.2 ) / (p1.1-p0.1), end : p1.1 } ), p0 := p1
}
}
AddClicked(){
GuiControlGet, low, , % this.hEditLow
GuiControlGet, high, , % this.hEditHigh
if (this.IsNumeric(low) && this.IsNumeric(high)){
this.AddPoint(low, high)
}
}
DeleteClicked(){
Gui, ListView, % hLV
row := LV_GetNext()
this.Points.RemoveAt(row)
this.BuildSegments()
this.SaveSettings()
}
IsNumeric(str){
if str is number
return true
return false
}
f(x){
for i, seg in this.Segments
if (x < seg.end)
return x*seg.k+seg.m
}
}
I think that Helgef's code might need a bit of tweaking though? An input value of 100 gives an empty string for the output