2
$\begingroup$

I'm using TabView as my base for an image analysis GUI for a collaborator to use.

I'd like to restrict moving onto the next tab until the preceding tab has been finished, in order to propagate the appropriate elements of each tab. But I want to be able to move backwards.

For instance as a toy example (and this is easily catchable):

DynamicModule[{tab = 1, fileName, ff}, 
 Column[{TabView[{
   1 -> PopupMenu[Dynamic[ff], {ColorNegate, Blur, EdgeDetect}], 
   2 -> FileNameSetter[Dynamic@fileName, "Open", {"Image" -> {"*.png", "*.jpg"}}], 
   3 -> Dynamic@ff[Import[fileName]]}, 
 Dynamic[tab]]}]]

I want to be able to control whether each tab is enabled, in the same way that e.g. Button can take an Enabled option. The option Enabled only applies to the entire TabView, so that doesn't work. I have 8 tabs at the moment in my actual app.

$\endgroup$
  • $\begingroup$ Ok, so what conditions are associated with enabling each tab? $\endgroup$ – Kuba Nov 13 '18 at 21:19
  • $\begingroup$ @Kuba, in this case, when an option has been picked (although with the PopupMenu it'll have a default, so that isn't a great example) and when a file has been chosen. On the most important tabs it can be tied to a button having been pressed in order to perform a calculation that takes a few seconds. $\endgroup$ – KraZug Nov 14 '18 at 10:00
3
$\begingroup$

Let me know if that fits your needs:

DynamicModule[
  {tab = 1, fileName, ff = None, maxTab = 1, labelStyle}
, labelStyle[i_]:=Function[item
  , Style[item, FontWeight->Dynamic[If[i <= maxTab, Bold, "Plain"]]]
  ]
; Column[{
    TabView[
      { labelStyle[1]@"Filter" -> PopupMenu[Dynamic[ff
          , {Automatic,Function[maxTab = Max[maxTab, 2]]}
          ]
        , {ColorNegate,Blur,EdgeDetect}
        ]
      , labelStyle[2]@"File" -> FileNameSetter[ Dynamic[fileName
          , {Automatic
            , Function[If[FileExistsQ[fileName],maxTab = Max[maxTab,3]]]
            }
          ]
        , "Open", {"Image"->{"*.png","*.jpg"}}
        ]
      , labelStyle[3]@"Processing" -> Dynamic[
          ff[Import[fileName]]
        , SynchronousUpdating->False
        , TrackedSymbols:>{ff, fileName}
        ]
      }
    , Dynamic[tab, If[# <= maxTab, tab = #]&]
    , ImageSize->Automatic  
    ]
  }]
]

enter image description here

$\endgroup$
  • $\begingroup$ Ooh, interesting, I hadn't thought that I basically just need to restrict what the maximum tab is, I was thinking I'd need to set it for each one. Think that'll do exactly what I need, thanks. $\endgroup$ – KraZug Nov 14 '18 at 11:17
  • $\begingroup$ Can I just ask why you added the SynchronousUpdating and TrackedSymbols to the third tab Dynamic? $\endgroup$ – KraZug Nov 14 '18 at 11:28
  • $\begingroup$ @KraZug becaus import + filter can be longer and by default Dynamic action freezes the front end, you want to avoid this. TrackedSymbols are there because otherwsie FE goes crazy even though it should not. $\endgroup$ – Kuba Nov 14 '18 at 11:30
  • $\begingroup$ Ok, just general good practice then essentially? $\endgroup$ – KraZug Nov 14 '18 at 11:38
  • $\begingroup$ @KraZug SynchronousUpdating should be added where it is needed :) See advanced dynamic functionality tutorial. And TrackedSymbols was a fix when I realized it went into a loop. $\endgroup$ – Kuba Nov 14 '18 at 11:56

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.