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$
4
  • 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$ Commented Jul 24, 2016 at 15:22
  • $\begingroup$ Added a piece of code that should allow fast testing ;) Thank you for your fast response ! $\endgroup$
    – Shikifuyin
    Commented Jul 24, 2016 at 16:08
  • $\begingroup$ This seems to be closely related: 83063 also 8237, 7756 $\endgroup$
    – Kuba
    Commented Jul 24, 2016 at 17:57
  • $\begingroup$ Is that quick fix ok? Dynamic[TabView[ Table[Slider[Dynamic[someTable[[#]]], {1, 5}] &@ iTabIndex, {iTabIndex, iTabCount}], Dynamic[iSelectedTab]]] $\endgroup$
    – Kuba
    Commented Jul 25, 2016 at 16:58

1 Answer 1

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$
9
  • $\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
    Commented Jul 24, 2016 at 16:45
  • $\begingroup$ The point is I'm trying to avoid mixing the model and the view as much as possible ... $\endgroup$
    – Shikifuyin
    Commented Jul 24, 2016 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
    Commented Jul 24, 2016 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
    Commented Jul 24, 2016 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$ Commented Jul 25, 2016 at 1:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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