1
$\begingroup$

What I'm trying to do is damn simple but it seems like Mathematica is extremely ill-designed for this ...

Here is a very simplified form of my code to show the basic idea. I have a variable number of tabs, depending on a dynamically set value, it already took me hours to find something that works :

Dynamic[TabView[ 
    Table[
        iTabIndex,
        {iTabIndex, iTabCount}
    ],
    Dynamic[iSelectedTab]
]]

where iTabCount is dynamically controlled by a slider in another part of the GUI. Now I want to have the content of each tab to contain dynamic controls (of course) over different parameters for each tab while sharing the same UI layout, but it just won't work ...

Dynamic[TabView[ 
    Table[
        Slider[ Dynamic[ someTable[[iTabIndex]] ], ... ],
        {iTabIndex, Count}
    ],
    Dynamic[iSelectedTab]
]]

===> Syntax error, iTabIndex is not connected anymore to the Table enumeration parameter when enclosed in Dynamic[] ... I NEED that Dynamic, otherwise controls nested in each tabs are pointless !

I tried working around by inserting a module (amongst other things) :

BuildTabUI[iTabIndex_] := (Dynamic)Module[
    {},
    Return[
        Slider[ Dynamic[ someTable[[iTabIndex]] ], ... ]
    ]
];

Dynamic[TabView[ 
    Table[
        BuildTabUI[iTabIndex],
        {iTabIndex, Count}
    ],
    Dynamic[iSelectedTab]
]]

Which does avoid the syntax error, but the slider is now unresponsive, despite the Dynamic enclosures inside BuildTabUI !

This would take seconds to code in C++ for any decent GUI engine ... how such a simple task can be so over-complicated ?

Can anyone please help me and give me a proper method to do this in a clean, efficient and generic way ? Thanks a lot in advance !

PS : Don't go easy on me with the technical details, I'm new to Mathematica but I'm an extremely experienced C++ programmer ... ;)

@JM, Test example :

param1 = param2 = param3 = 1;
iSelectedTab = 1;
iTabCount = 1;
someTable = { param1, param2, param3 };

Slider[ Dynamic[iTabCount], {1,3,1} ]

Dynamic[TabView[ 
    Table[
        Slider[ Dynamic[ someTable[[iTabIndex]] ], {1,5} ],
        {iTabIndex, iTabCount}
    ],
    Dynamic[iSelectedTab]
]]

I expect a tabview of 1-3 tabs, depending on first slider, each containing a nested slider controlling param1, param2, param3 ... Hope this is straightforward enough ... Thank you for your attention !

$\endgroup$
  • 3
    $\begingroup$ Altho we like minimal examples, this is a bit too minimal. Can you come up with an example that can actually be run by potential helpers? $\endgroup$ – J. M. will be back soon Jul 24 '16 at 15:22
  • $\begingroup$ Added a piece of code that should allow fast testing ;) Thank you for your fast response ! $\endgroup$ – Shikifuyin Jul 24 '16 at 16:08
  • $\begingroup$ This seems to be closely related: 83063 also 8237, 7756 $\endgroup$ – Kuba Jul 24 '16 at 17:57
  • $\begingroup$ Is that quick fix ok? Dynamic[TabView[ Table[Slider[Dynamic[someTable[[#]]], {1, 5}] &@ iTabIndex, {iTabIndex, iTabCount}], Dynamic[iSelectedTab]]] $\endgroup$ – Kuba Jul 25 '16 at 16:58
4
$\begingroup$

Here's a quick mockup of what it sounds to me like you are attempting:

DynamicModule[{iTabCount, iSelectedTab, tabSlider, tabUI},
  iTabCount = 5;
  tabSlider[_] = 0;

  tabUI[i_] := 
    Column[{
      Slider[Dynamic @ tabSlider[i], {-1, 1}], 
      Dynamic @ Plot[Sin[x + tabSlider[i]], {x, -2 Pi, 2 Pi}]
    }];

  Column[{
    Dynamic @ TabView[Array[tabUI, iTabCount], Dynamic @ iSelectedTab],
    Slider[Dynamic @ iTabCount, {1, 10, 1}],
    Slider[Dynamic @ iSelectedTab, {1, Dynamic @ iTabCount, 1}]
  }]
]

enter image description here

$\endgroup$
  • $\begingroup$ Yeah ! That's exactly what I need ! However it is a bit tricky to translate your code sample in my own code, can you develop a bit on the details ? What's the difference between Dynamic[...] and Dynamic @ ... ? Is the global DynamicModule enclosing mandatory ? What is its precise role here ? What would take the place of tabSlider[i], in my code, is actually nested associative arrays I use to emulate C-like "struct" to have some object-oriented code support, but tabSlider seems to be a function in your code ? Thanks a lot for your answer, I'll adapt my code to this template if required ;) $\endgroup$ – Shikifuyin Jul 24 '16 at 16:45
  • $\begingroup$ The point is I'm trying to avoid mixing the model and the view as much as possible ... $\endgroup$ – Shikifuyin Jul 24 '16 at 16:52
  • 1
    $\begingroup$ In my code tabSlider is an "indexed object" and it allows me essentially to scope an arbitrary (dynamically generated) number of Symbols. Please reference: (6511), (13440) $\endgroup$ – Mr.Wizard Jul 24 '16 at 17:20
  • 1
    $\begingroup$ Alright I think I get it, the problem seems to be with the way I build my "objects" ... everything else is working fine now ... Those "indexed objects" seems to be exactly what I need in fact (scoping dynamically generated symbols), I didn't know about those ! I will setup things accordingly then. Thanks a lot again ! About DynamicModule, I was suspecting it to be doing some kind of implicit linkage in a context of dynamic symbols working together, but it seems its not the case and only deals with scoping, as expected from the documentation, again thanks a lot, you saved me a lot of time ! ;) $\endgroup$ – Shikifuyin Jul 24 '16 at 17:33
  • 3
    $\begingroup$ @MrWizard Use Dynamic@iselectedTab in the Dynamic@Tabview expression to get two way communication with the bottom most slider. $\endgroup$ – Jack LaVigne Jul 25 '16 at 1:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.