VB hacks - toggle buttons


(joule) #1

I just thought I share an example of how to make toggle buttons by using some ViewBuilder tricks. Both text button toggles or bitmap toggles can be made this way.

They look and behave pretty decent, but they are indeed not “100%”. Inversed font colors and mouse-over highlights will misbehave, but in a way that in most cases shouldn’t be too disturbing (depending on your theme).

Here is some code to show the principle. Feel free to make a proper class out of it if you find it useful :slight_smile:

Click to view contents
local vb = renoise.ViewBuilder()
local text_toggle_val = renoise.Document.ObservableBoolean(false)
local bitmap_toggle_val = renoise.Document.ObservableBoolean(true)
local bitmap_toggle = vb:checkbox {
  width = 100,
  height = 50,
  value = true,
  value = bitmap_toggle_val.value,
  bind = bitmap_toggle_val
}
bitmap_toggle:add_child(
  vb:vertical_aligner {
    mode = "center",
    width = 100,
    vb:horizontal_aligner {
      mode = "center",
      vb:row {
        margin = -2,
        vb:column {
          width = 98,
          vb:row {
            height = 48,
            vb:checkbox {
              active = false,
              value = true,
              width = 200,
              height = 200,
              value = bitmap_toggle_val.value,
              bind = bitmap_toggle_val
            }
          }
        }
      }
    }
  }
)
bitmap_toggle:add_child(
  vb:vertical_aligner {
    mode = "center",
    width = 100,
    vb:horizontal_aligner {
      mode = "center",
      vb:bitmap {
        bitmap = "Icons/TrackScope_M.bmp",
        mode = "body_color",
        notifier = function()
          bitmap_toggle_val.value = not bitmap_toggle_val.value
        end
      }
    }
  }
)
local text_toggle = vb:checkbox {
  width = 100,
  height = 50,
  value = text_toggle_val.value,
  bind = text_toggle_val
}
text_toggle:add_child(
  vb:vertical_aligner {
    mode = "center",
    width = 100,
    vb:horizontal_aligner {
      mode = "center",
      vb:row {
        margin = -2,
        vb:column {
          width = 98,
          vb:row {
            height = 48,
            vb:checkbox {
              active = false,
              value = true,
              width = 200,
              height = 200,
              value = text_toggle_val.value,
              bind = text_toggle_val
            }
          }
        }
      }
    }
  }
)
text_toggle:add_child(
  vb:vertical_aligner {
    mode = "center",
    width = 100,
    vb:horizontal_aligner {
      mode = "center",
      vb:text {
        text = "Toggle Button",
      }
    }
  }
)
local presentation = vb:row {
  margin = 20,
  spacing = 30,
  vb:column {
    vb:text {
      text = "Text toggle",
      align = "center",
      width = 100,
    },
    text_toggle,
  },
  vb:column {
    vb:text {
      text = "Bitmap toggle",
      align = "center",
      width = 100,
    },
    bitmap_toggle,
  },
  vb:column {
    vb:text {
      text = "Normal vb:button",
      align = "center",
      width = 100,
    },
    vb:button {
      text = "Normal button",
      width = 100,
      height = 50,
    }
  }
}
return presentation

Gifanim:

7435 toggles.gif


(Raul (ulneiz)) #2

Very interesting.I use a very different method. I simply use a hidden checkbox to be able to change the color of the button.Actually, the intention is to be able to replace the checkbox with a button with its characteristics, colors, bitmap, text …That way you do not have to name the checkbox outside. Using just one button, it takes up less space.Only you will have a hidden checkbox working.

Lately I have been able to build a virtual piano with buttons with the original look of the piano, with the keys superimposed correctly.If I have time I will share it, since I have not seen something like that in the forums…

I love all these tricks, thanks!!!


(joule) #3

I don’t think there is any other way than the above (or fetching/parsing renoise preferences) to build a toggle button with the correct active color. Or maybe that’s what you meant?

I’m guessing that you use the checkbox notifier and then set “checkbox.value == true” as a trigger for this function? Kind of like an invisible relay to do other stuff?

If that’s the case, I recommend using Document observables instead. Using GUI elements for this is not the ‘clean way’ of doing it :wink:

Something like the below can be very handy if you want to trigger the same function in several different ways (i e from several different places). Also note in the Documents API that there are other observable document types.

local do_something = renoise.Document.ObservableBang()

do_something:add_notifier(
function()
  print("the do_something object was banged! anything can happen here.")
end
)

do_something:bang()