Custom sliders demo, including the "panning slider"

I recommend not using the XY pad if you only need one dimension. Sliders should work fine, and the XY pad has the drawback of requiring the user to switch ā€˜Mouse warping’ (in prefs), if you don’t want mouse movements to be strange in many circumstances.

I agree.A slider is better because it is thinner, slower, easier to control…I’m doing tests with both, with the xypad and with the slider. For a single direction, the slider for fine control is better.

Here is a one-bar demo tool:7994 ulneiz.custom_sliders_v1.0.xrnx

@Joule. Pleasek would you be able to take a look at the code, so that the slider head button remains active at all times?I can not do that.I have tried to use the ā€œpressedā€ property of the button to hide / show the same button. Even using a timer. And there is no way.

How do you get this?

  1. Buttons need not be unactive. You can just quickly hide/show them, unnoticably, when they are clicked. The underlying control should then catch the mouse click.

Thanks!

Here is the viewbuilder portion, CUSTOM_VOL_BT is the id of the button:

vb:row { spacing = -919,
    vb:column { spacing = -21, margin = -1,
      vb:row { spacing = -26,
        vb:row {},
        vb:slider {
          id = "CUSTOM_VOL_SLIDER",
          height = 21,
          width = 947,
          min = -1,
          max = 889,
          value = 1,
          notifier = function(value) vws["CUSTOM_VOL_BT"].active = true vws["CUSTOM_VOL_BAR"].width = value+2 vws["CUSTOM_VOL_RW_WIDTH"].width = value+2 slider_value( value, 1 ) end
        }
      },    
      vb:row {
        style = "plain",
        height = 21,
        width = 923
      }
    },
    vb:row { spacing = -3,
      vb:column {
        id = "CUSTOM_VOL_RW_WIDTH",
        width = 1,
        vb:space { height = 5 },
        vb:button {
          id = "CUSTOM_VOL_BAR",
          active = false,
          height = 9,
          width = 1,
          color = { 120,120,000 },
        },
      },
      vb:button {
        id = "CUSTOM_VOL_BT",
        active = false,
        height = 19,
        width = 31,
        text = "..",
        color = { 090,090,000 },
        pressed = function() end,--function() micro_timer_btt_vol(20) end,
        notifier = function() vws["CUSTOM_VOL_BT"].active = false end,
        midi_mapping = "x"
      }
    }

My bad - the trick was slightly different than i remember. By quickly doing a remove_child/add_child on a rack containing the button, it will act as if it was ā€œtransparentā€ on the xypad.

I’ve attached a simple example!

PS. Some further advise for the future: if you need to catch the actual coordinates of the click, you’ll have to do that via the xypad notifier (further implying that the button notifiers sets/unsets some kind of ā€œis_pressedā€ flag for some kind of canvas system knowing what’s going on).

7996 joule.no0b.testpad.xrnx

I’ve love to have the time to properly digest these awesome tricks and implement them in my own tools.

Kudos for wrapping it up so nicely, joule smile.png

Once again, as it is necessary to read the parameters of the selected note column. I use a timer that detects the line change. I want to remember that the API has a problem every time it jumps to the first line of each pattern after reading the later one. Returns the parameters of the first line of the previous pattern, in the first line, of the selected pattern.This should be corrected!

I remember you mentioned this, but do you have snippet which demonstrates the problem - something you can share with us?

I’ve love to have the time to properly digest these awesome tricks and implement them in my own tools.

expanding the topic a bit… xCanvas? :wink:

I’d be happy to give any input I can. The last conclusion I came to when dabbling with these things was that I probably need some kind of ā€œbehaviorā€ class for objects - if the system is to be flexible enough and not just ad hoc solutions for dragging buttons et c… Someone with a proper education should know exactly how to lay these things out? :slight_smile:

My bad - the trick was slightly different than i remember. By quickly doing a remove_child/add_child on a rack containing the button, it will act as if it was ā€œtransparentā€ on the xypad.

I’ve attached a simple example!

PS. Some further advise for the future: if you need to catch the actual coordinates of the click, you’ll have to do that via the xypad notifier (further implying that the button notifiers sets/unsets some kind of ā€œis_pressedā€ flag for some kind of canvas system knowing what’s going on).

@Joule. Thank you very much for this particular code! This little detail remove_child/add_child is great for many things! For the moment, I can confirm that it does not matter if you use xy_pad or a slider, since the function is executed from the pressed property of the button.

I like the code in particular because you have defined a class for the button. It is a great example of how to create a class, even defining an ā€œidā€ that is not a string and then converting it with tostring. Thanks for sharing!

Personally, I really like that the look of the UI looks nice and beautiful. These things help a lot!

Someone with a proper education should know exactly how to lay these things out? :slight_smile:

Well, there are not many people in these forums that know how to do these things. :slight_smile:

Well, this is the final result:

7997 custom_slider_2.gif

Now the button numbers are read clearer, easier to read. This is an animated gif. But the real result is fine and precise. Sliders and CTRL are used for greater precision.

The panning slider is the most complicated. But with more layers it is possible to build it.With all these tricks, the result is pretty good for a customized look…

Note: the panning slider has an error of 1 pixel in its bar. It’s silly, but it shows.It’s a matter of adjusting it.

Here the old demo:

[sharedmedia=core:attachments:7992]

I remember you mentioned this, but do you have snippet which demonstrates the problem - something you can share with us?

Yes, give me a little time and I will share here a demo tool with the problem. Follow this same thread.

I remember you mentioned this, but do you have snippet which demonstrates the problem - something you can share with us?

@danoise.Here is a demo tool that can reproduce the problem:

7998 ulneiz.microedit_v1.0.xrnx.zip

Steps:

  1. Unzip the zip. Install the tool and load the attached song.
  2. Enable the top checkbox inside the tool to activate the timer.
  3. Play the song in Renoise (follow the player must be enabled).
  4. Important! With a little skill, try to stop the song on the first line of the next pattern.The result is that it reads the first line of the previous pattern, when the cursor is in the current pattern.This should not happen.It is not expected.
  5. Repeat step 4 from the second line. The reading of the data will be correct, of the current pattern.

Well, if you move with the mouse cursor, without the song playing, there is no problem reading data on the first line.

This demo tool does not have a pattern skip notifier, so it does not updates the data for each slider.It would be necessary to check if in this case the problem persists as well.

Well, this is the final result:

It seems to be working :slight_smile:

Just a note… when using tricks like these, It might be a good idea to test drive the GUI with different themes, including inverted themes and whatnot. At least if you plan to use them in public tools. I’m not completely sure that a rack with ā€˜plain’ style as overlay will appear consistent in all themes and situtations where it happen to work with the default-ish themes, so It’s probably a good idea to check that. Personally, I think it’s best to stick to native controls whenever it’s possible.

It seems to be working :slight_smile:

Just a note… when using tricks like these, It might be a good idea to test drive the GUI with different themes, including inverted themes and whatnot. At least if you plan to use them in public tools. I’m not completely sure that a rack with ā€˜plain’ style as overlay will appear consistent in all themes and situtations where it happen to work with the default-ish themes, so It’s probably a good idea to check that. Personally, I think it’s best to stick to native controls whenever it’s possible.

Is there any way to create a function that forces the reload of the entire GUI of the tool window?If this were possible, it would be simple to offer a section of preferences with the colors to choose, and that each user chooses whoever the color they want.

Unfortunately, the current API does not have a way to access Renoise theme colors (skins).I miss being able to access certain colors, such as the selection color, for example.Anyway, the colors that I have chosen (quickly) are quite dark. But making it look good on all themes is impossible.

If there was a way for the user to choose several colors, and with just a push of a button the GUI of the window would be updated would be great. Any ideas?

…

A separate topic, I’m making another ā€œbigā€ tool that uses sliders, and I’m not going to use this masking trick, keeping the original sliders.

That said, I remind Danoise to point out the need to update the sliders to be able to invert them, and be able to use them for panning, to the left and right, and to add the double-click to establish a reset or return value in the API.

The properties could be these:

vb.slider {
  id
  height
  width
  min
  max
  value
  notifier
  tooltip
  bind

  *return = value (double click of mouse)... 'return' or 'reset'
  *mode = string --> "default", "reverse" or "panning", 3 modes
  *pressed = function() --(why not?)
  *released = function() --(why not?)
}

--in "reverse" if vertical, from top to bottom; if horizontal, from rigth to left.
--in "panning" if it is horizontal the bar would work from the center to the right or left...
--similar to minislider and review xypad

Precisely, these tricks of this thread are made by the lack of these properties…

Edit:Maybe it is necessary that the properties min , max and value accept negative values … ???

[sharedmedia=core:attachments:7997]

7999 custom_sliders_themes_1.png

Inverse, Default, Redux themes… Perhaps in the clearest subjects it would require lighter colors. I think that with 2 intensities it would be enough (dark and clear).

Is there any way to create a function that forces the reload of the entire GUI of the tool window?

Ok, I think I am already know how to do it.With storing the new values in a table or in an xml and a button to apply would be enough. :ph34r:Anyway, I would like to know if the API has ā€œsomethingā€ that can be used to reload the complete GUI, without closing the window.

Not completely sure what you mean…

  1. You can’t change theme colors from the tool. At least not live, I think.

  2. If you need to do something like a complete ā€œrefreshā€ of a tool gui, you can rebuild the gui and remove/add_child it from a top-most rack acting like a container. Even simpler should be to :close() the old dialog and open a fresh one with the gui rebuilt. I can’t see a case where you’d want to do this, unless you’re doing something ā€œwrongā€ā€¦ Viewbuilder rendering seems to be very consistent, except for some rack resize issues where some trial and error might be needed when scripting.

Btw… if you were talking about re-using theme colors for button colors, it’s totally possible to read the XML file containing the color presets. I discussed this briefly with Danoise some years ago, suggesting he should add it to his cLib. It’s not that difficult, but If I recall correctly, he was hesistant due to the testing required to verify it on all OS:es. Maybe it wasn’t just that important :slight_smile:

  1. You can’t change theme colors from the tool. At least not live, I think.

That’s true - just like with things like view presets, keyboard shortcuts etc. the API does not (will not) allow a tool to redefine these things.

Which makes sense IMO - the tool should respect the user preference, not the other way around :slight_smile:

And yes, I did import colors from the user theme, but it was mostly a ā€œproof of conceptā€ and not something I was ready to put into released tools.

Might indeed revisit this :slight_smile:

Anyway, I would like to know if the API has ā€œsomethingā€ that can be used to reload the complete GUI, without closing the window.

You need some code that either updates the view elements (you can always change the color if you have a reference around), or something that pulls down/recreates the entire thing.

Which approach you prefer, is of course up to you.

Also, the observable pattern is great if you want avoid having to ā€œmanageā€ a GUI every time some little value changes in the logic of your tool.
Observables are closely related to the Document API, which is what tool preferences are using.

Not completely sure what you mean…

  1. You can’t change theme colors from the tool. At least not live, I think.

  2. If you need to do something like a complete ā€œrefreshā€ of a tool gui, you can rebuild the gui and remove/add_child it from a top-most rack acting like a container. Even simpler should be to :close() the old dialog and open a fresh one with the gui rebuilt. I can’t see a case where you’d want to do this, unless you’re doing something ā€œwrongā€ā€¦ Viewbuilder rendering seems to be very consistent, except for some rack resize issues where some trial and error might be needed when scripting.

Btw… if you were talking about re-using theme colors for button colors, it’s totally possible to read the XML file containing the color presets. I discussed this briefly with Danoise some years ago, suggesting he should add it to his cLib. It’s not that difficult, but If I recall correctly, he was hesistant due to the testing required to verify it on all OS:es. Maybe it wasn’t just that important :slight_smile:

Maybe with remove_child and add_child it is possible to change some color live.

Anyway, I’m contemplating several possibilities here. Well changing the color in some table and then pressing an update button that changes the color of some buttons (basically). Or, saving those values in an preferences xml. I’m thinking about building my own RGB color panel so I can save several values for several types of buttons. I’m thinking how to do this to take advantage of it in various tools. In the last months I have learned to build all these things.

On the topic of reading the XML that contains the colors of the theme, there is always some added difficulty, such as the fact that it is fully compatible with all OS. I suppose that in each system, the XML will be saved in a different site.

I have a tool made that manipulates folder addresses. I know it works well in Windows, because I’ve tried it. But I do not know if it will work well in MAC or Linux, because of the file paths, double bar //, \ and so on …

On the other hand, seeing that all this has relation with the GUI, I have noticed that the use of textures in the skins (themes of Renoise) drastically affects the performance when you hide or show multiple objects (visible true / false) or removes add multiple objects (remove_child, add_child). The use of textures can affect important lags in large window tools (resolutions close to 1920x1080 or higher) … I think I will open a new thread on this issue.

@Joule and @Danoise.Actually, the interesting thing is that the tool has access to the colors of the theme used (skin of the user), to adapt the tool to these colors. It is not about modifying the colors of the user’s theme, but about adapting the colors of the tool according to these colors.

It would be interesting to have access to the value of the theme colors (import them into a table inside the tool for later use), to be able to use them in the tool. A clear example is: build your own checkbox. What color do you use to mark it?Surely it will not correspond to the theme (skin) of the tool of the user.

That’s true - just like with things like view presets, keyboard shortcuts etc. the API does not (will not) allow a tool to redefine these things.
Which makes sense IMO - the tool should respect the user preference, not the other way around :slight_smile:

Lo and behold… The renoise.app API reveals that both : load_theme () and :save_theme() methods are available. So, it’s actually possible to make a custom theme editor tool that builds/loads a theme.xml file whenever the user moves some slider.

Not that any sane person would waste his spare time like that… but it should be possible :slight_smile:

I keep writing down more things that I have been checking.The use of textures , also drastically affects the change of color of some object.For some reason, textures are a burden, not only when adding or removing an object remove_child / add_child or making visible true / false (both cases are equally fast).This is very noticeable if you have a tool with a large window with multiple objects.

The automatic adjustment of the dimensions of the windows / panels and the change of color go much slower with textures.

You can have thousands of defined objects in LUA, through classes or not and iterating or not. If you do not have the textures enabled, the whole tool goes ultra fast. If you activate the textures, there is a very noticeable problem with lag.which also affects the performance of the Renoise window. If the tool suffers and presents lag, it is also presented by the Renoise window, for example, in the course of playing a song (it also receives lag).Maybe this matter deserves a separate thread.

Is it possible that the API has a problem with the textures or lack of optimization or something strange? The GUI of the window tool should go much more fluid with textures. If you want to build a large window tool, with multiple objects, that is dynamic with constant size changes or live color changes (through sliders, for example), having the textures activated becomes a real problem.

In case there is any doubt, I am talking about: Preferences/Theme: Textures --> (Default, Dotted, Eddged, Jeans, Metal).All textures have the same lag. In case of using large dynamic windows tools, with multiple objects, it is mandatory to deactivate the textures, Textures --> None.

The textures are in the folder …\Renoise 3.1.1\Resources\Skin\Textures.All are of BMP format (70KB, very little).Even Renoise receives a notorious lag every time the textures are loaded.Is it possible that it has to do with the continuous resizing of the textures?If you are changing live colors using sliders, you are also modifying a dimension of the slider.

Have you experienced in depth on this subject?Could not this be optimized so that there was no lag when using textures?Most user themes (skins) use textures.By the way, I really like the look that can be achieved with the textures, but I do not like at all that more than notorious lag.

For those who have a very large screen, and tools with a large window with multiple objects (stylish panels, buttons, sliders, pop-up windows …), it is advisable not to use textures (Renoise 3.1.1 x64).

I think this should be reviewed under the hood of Renoise.Taktik mentioned many months ago that he made an attempt to adapt Renoise for higher resolutions. I consider it imperative to use vectors for the resizing of icons and to eliminate any type of textures added with BMP, PNG format images … I would not mind if Renoise had a flatter aspect if it guarantees that the GUI works more smoothly in 2K resolutions , 4K, etc.

Have you tried the Ableton 10 zoom?Without wishing to compare the DAWs, I honestly believe that Renoise is very improvable in its GUI, and that it has a direct impact on its overall performance. There are still many people who use Renoise with little powerful laptops (low-powered graphics card). It is mandatory not to use textures for a better experience.Well, you could be very clever and say, then turn off the textures. But that is not the issue.

Edit: AppData\Roaming\Renoise\V3.1.1\ Config.xml… (Skin Colors) … None

Does anyone want to have fun?

8000 custom_color_sliders_x3.gif

I can not build a script that is able to control the 3 sliders to behave simultaneously. The behavior should be the same as the ā€œMulti Volumesā€ tool of Afta8 (an incredible tool), but with 3 sliders.Could someone create a script that controls all 3 sliders simultaneously, regardless of the slider you are scrolling? Each slider must have its notifier free to execute specific functions.

8001 custom_color_sliders_x3_2.gif

I have succeeded in combining the three sliders. But I still have problems in the limits, because when I go over some limit <0 or> 255 the slider loses the distance when I change direction.This is part of the code that is responsible for synchronizing them:

---
pht_clr_nte_off_variance = 0
pht_clr_nte_off_sliders_x3 = {}
---
function pht_clr_nte_off_sel_last()
  pht_clr_nte_off_sliders_x3 = { vws.PHT_CLR_NTE_OFF_SLR_R.value, vws.PHT_CLR_NTE_OFF_SLR_G.value, vws.PHT_CLR_NTE_OFF_SLR_B.value }
end
---
function phr_clr_nte_off_sel_update_x3( value, rgb )
  if ( pht_clr_nte_off_anchor == true ) then
    if ( pht_clr_nte_off_sliders_x3[2] - pht_clr_nte_off_variance >= 0 ) and ( pht_clr_nte_off_sliders_x3[2] - pht_clr_nte_off_variance <= 255 ) then
      if ( vws.PHT_CLR_NTE_OFF_SLR_G.value ~= pht_clr_nte_off_sliders_x3[2] - pht_clr_nte_off_variance ) then
        vws.PHT_CLR_NTE_OFF_SLR_G.value = pht_clr_nte_off_sliders_x3[2] - pht_clr_nte_off_variance
        print("G")
      end   
    end
    if ( pht_clr_nte_off_sliders_x3[3] - pht_clr_nte_off_variance >= 0 ) and ( pht_clr_nte_off_sliders_x3[3] - pht_clr_nte_off_variance <= 255 ) then
      if ( vws.PHT_CLR_NTE_OFF_SLR_B.value ~= pht_clr_nte_off_sliders_x3[3] - pht_clr_nte_off_variance ) then
        vws.PHT_CLR_NTE_OFF_SLR_B.value = pht_clr_nte_off_sliders_x3[3] - pht_clr_nte_off_variance
        print("B")
      end
    end
    if ( pht_clr_nte_off_sliders_x3[1] - pht_clr_nte_off_variance >= 0 ) and ( pht_clr_nte_off_sliders_x3[1] - pht_clr_nte_off_variance <= 255 ) then
      if ( vws.PHT_CLR_NTE_OFF_SLR_R.value ~= pht_clr_nte_off_sliders_x3[1] - pht_clr_nte_off_variance ) then
        vws.PHT_CLR_NTE_OFF_SLR_R.value = pht_clr_nte_off_sliders_x3[1] - pht_clr_nte_off_variance
        print("R")
      end
    end
    pht_clr_nte_off_sel_last()
    if ( pht_clr_nte_off_variance ~= pht_clr_nte_off_sliders_x3[rgb] - value ) then
      pht_clr_nte_off_variance = pht_clr_nte_off_sliders_x3[rgb] - value
      print("pht_clr_nte_off_variance",pht_clr_nte_off_variance )
    end
  end
end
---

I use an empty table to store the initial values of the 3 sliders. And a custom checkbox that also executes the update of said table.The problem I had was to set the initial values first, and get the change value to add / subtract each slider equally.The result is acceptable, but not perfect. I would like the sliders to ā€œignoreā€ the limits, so that when they change direction, they do not lose the distance between them.