TabbedView  An array of CompositeViews (or ScrollViews) with tabs for switching 


by jostM,   July 9, 2008 version 1.21

Change history at bottom.

  

Class Methods


 *new(view,bounds,labels,colors,name,scroll) returns a TabbedView object

    view a view. if nil, then a new window is created

    bounds Rect .  if nil then the parent Rect is used

    labels an array of strings. determines how many tabs there are. default ["tab1", "tab2", "tab3"]

    colors an array of colors. if the array is smaller than the amount of labels, the color series repeats.

  For convenience, a color scheme is automatically created using these colors. 

  You cannot use gradients here, because the tabs are drawn with Pen.

  Gradients only work with background_;

  Custom color schemes and shapes can be controlled with instance variables

  or with the *new variations below.

    name a name for the window if a new window is created (view==nil) -- default " "

    scroll boolean defaults to false. It substitutes the CompositeView with a ScrollView.

 Convenience method variations on *new for quick styling :

 

 *newBasic

 *newColor

 *newColorLabels

 *newFlat

 *newTall

 *newTransparent

 *newPacked

     

   

Methods/Variables:


  view  returns the container for all the views

  views  returns  an array of Composite/Scroll Views


  add ( label )  string adds a tab with label ; returns the Composite/Scroll View

  insert ( index , label )  int, string inserts a tab  at index with label string ; returns the Composite/Scroll View

  removeAt( index )  int remove tab at Index.

   

  focus ( index )  int selects one of the tabs

  activeTab   returns the index of  the focused tab 

   

  focusActions_(array)    an Array  of user onFocus functions.

  unfocusActions_ (array)  an Array of user onUnfocus functions.

   

  tabPosition_ ( symbol )  \left, \top, \right, or \bottom.

  followEdges_ ( bool )  default true. Set tabs parallel or perpendicular to container edges.

  resize_ ( val )  int sets the resize flag (1-9 ).   default 1. ;

   

  labelColors_ ( colorarray ) Array of Colors for the Tabs.

  unfocusedColors_ (colorarray ) Array of  Colors for the unfocused Tabs

  backgrounds_ (colorarray ) Array of Colors for the CompositeViews 

  stringColor_ ( color ) a Color

  stringFocusColor_ ( col ) a Color

   

  labelPadding_ ( int )   if autosizing is on, then this determines left and right padding from th label text

  tabWidth_ (int )  int or  \auto ;  a fixed tab width, or "auto" for automatic tab width (default "auto", unless using themes)

  tabHeight_ ( int )  int or  \auto ;  a fixed tab height, or "auto" for automatic tab height (default "auto", unless using themes)

  tabCurve_ ( int )   ; the radius in pixels of the rounded tab corners

   

  swingFactor_( float )  float ;  a multiplication factor for a string/tab width for GUI.swing only. default  7.0

    relativeOrigin_ (bool)  not working for some objects such as SCTextView presently, becuase of  SC bugs. 

            Also, please see the cautions under SCCompositeView

     

   

Usage:


use CompositeView style GUI

(

t=TabbedView(name:"** this is a mock preferences pane **");


ActionButton(t.views[0],"go to next tab ",{t.focus(1)}).bounds_(Rect(50,50,200,100));

)


use FlowView style GUI


(

t=TabbedView(); // use Flow Style


t.views[0].flow({|w| 

GUI.button.new(w,Rect(50,50,250,50))

.states_([["control the tab with method 'focus' -->"]]).action_({t.focus(1)})

});

t.views[1].flow({|w| 

GUI.button.new(w,Rect(50,50,200,100))

.states_([["go to last tab"]]).action_({t.focus(2)})

});

)




quick styling with variations on  *new:

(There are some color differences for swing)


TabbedView.newBasic


TabbedView.newColor


TabbedView.newColorLabels


TabbedView.newFlat


TabbedView.newTall


TabbedView.newTransparent


TabbedView.newPacked(nil,nil,Array.fill(20,{|i| i.asString})); //very good for tons of tabs :



set tabPosition and followEdges:

live switching adjusts positions of contents if you use  .flow  .

for the moment live switching does not work with many objects because of an SC source code bug.

If your objects are encased in FlowViews at every level (including the object contents itself), all should be OK. Otherwise, you have to set the tab position before you add objects


(

v=TabbedView.newColorLabels(nil,nil,Array.fill(5,{arg i; var q="aa"; i.do{q=q++"a"}; q })); //default

v.views[0].flow({arg w;

ActionButton(w,"tabs top",{v.tabPosition_(\top)},300,50);

w.startRow;

ActionButton(w,"tabs left",{v.tabPosition_(\left)},148,50);

ActionButton(w,"tabs right",{v.tabPosition_(\right)},148,50);

w.startRow;

ActionButton(w,"tabs bottom",{v.tabPosition_(\bottom)},300,50);

GUI.button.new(w,300@50)

.states_([["set followEdges=false",Color.black,Color.red.alpha_(0.2)],

["set followEdges=true",Color.black,Color.green.alpha_(0.2)]])

.action_({arg b;(b.value==1).if{v.followEdges_(false)}{v.followEdges_(true)};});

});


)


TabbedView.newColorLabels(nil,nil,Array.fill(25,{|i| "tab"++i.asString})).tabPosition_(\right).followEdges_(false);


TabbedView.newTall(nil,nil,Array.fill(5,{|i| "tab"++i.asString})).tabPosition_(\left);


TabbedView.newTall(nil,Rect(100,500,400,100),Array.fill(5,{|i| "tab"++i.asString})).tabPosition_(\bottom);


Drag objects from one tab to another (under cocoa only at the moment):

(

v=TabbedView.newColorLabels;

n = GUI.dragSource.new(v.views[0], Rect(50, 50, 140, 24));

n.object = "Drag me to Tab2";

 GUI.textView.new (v.views[1], Rect(50, 50, 140, 80));

)


add, removeAt, insert  tabs

defaults on *new, but other thems use fixedwidths:


v=TabbedView.newColor


v.add("I am last")


v.insert(2,"squeeze me in")


v.removeAt(2)


resize_()

( 

w=GUI.window.new.front;

v=TabbedView.newColorLabels(w,Rect(40,40,280,280),Array.fill(12,{|i| "tab"++i.asString}),relativeOrigin:true).tabPosition_(\right).followEdges_(false);

v.resize_(5);

GUI.slider.new(v.views[0],Rect(10,80,200,30)).resize_(2);

) 


nest TabbedViews & use scrolling

uses  scroll:true in the inner tab

(

v=TabbedView.newPacked(nil,Rect(200,200,600,400).insetBy(20,20),["1","2","3"])

.tabHeight_(40).tabPosition_(\right).followEdges_(false);


q=TabbedView.newColorLabels(v.views[0],nil,["tab1.1","tab1.2","tab1.3"], scroll: true)

.tabPosition_(\right).resize_(5).followEdges_(false);

q.views[0].flow({ arg w;

78.do({ arg i;

b = GUI.button.new(w, Rect(rrand(20,300),rrand(20,300), 75, 24));

b.states = [["Start "++i, Color.black, Color.rand],

["Stop "++i, Color.white, Color.red]];

});

});

GUI.slider.new(q.views[1],q.views[1].bounds.insetBy(50,50));

)




user functions:   focus and unfocus

     turn on/off scopes , e.g. 

     

( 

v=TabbedView.new();

v.focusActions[1]={"1 is focused".postln};

v.unfocusActions[1]={"1 just unfocused".postln};

)



default autosizing tabs

defaults to auto on *new, but other themes use fixedwidths:


(

TabbedView.new(nil,Rect(150,100,400,500),["1","two","threeeeeeeeeeee","four","5"]); 

)


(

v=TabbedView.newFlat(nil,Rect(150,100,400,300),["1","two","threeeeeeeeeee","four","5"]); 

v.tabWidth_(\auto);

)


fixed tab sizes

(

TabbedView(nil,nil,["1","two","three","four","5"]).tabWidth_(70);  

)


set font 


Swing fonts only work within certain limits for now.

(

v=TabbedView.newBasic.font_(GUI.font.new("Monaco",9)).tabHeight_(18);


)


(

v=TabbedView.newBasic.font_(GUI.font.new("Helvetica",14)).tabHeight_(\auto);


)


(

v=TabbedView.newTall.font_(GUI.font.new("Helvetica",18)).tabPosition_(\left);


)



set colors with an argument to .new


Colors can wrap around if there are less than there are labels.

   Unfocused colors are calculated automatically.

(

v=TabbedView(nil,nil,Array.fill(8,{|i| i.asString}),

[Color.red.alpha_(0.2),Color.blue.alpha_(0.2),Color.yellow.alpha_(0.2)]);

//Colors can wrap around 

)



set colors very specifically to your own taste using set methods


 

(

v=TabbedView.new(nil,nil,["one","two","three"]); 

//Colors can wrap around 

v.labelColors_([Color.rand,Color.rand,Color.rand]);

)


(

v=TabbedView.new(nil,nil,["one","two","three"]); 

v.labelColors_([Color.red,Color.blue,Color.yellow]);

v.unfocusedColors_([Color.red.alpha_(0.1),Color.blue.alpha_(0.1),Color.yellow.alpha_(0.1)]);

v.backgrounds_([Color.red.alpha_(0.1),Color.blue.alpha_(0.1),Color.yellow.alpha_(0.1)]);

)



adjust padding and curves for small autowidth

labelPadding  only has an effect on autowidth


(

v=TabbedView(nil,nil,Array.fill(20,{|i| i.asString}));

v.labelPadding_(8);  //tighter padding

v.tabCurve_(3);   //sharper curves

v.stringColor_(Color.black);

v.backgrounds_([Color.white.alpha_(0.3)]);

)


or simply use *newPacked:


(

v=TabbedView.newPacked(nil,nil,Array.fill(20,{|i| i.asString}));

)


adjust tab height and curves


super flat and elegant

(

v=TabbedView(nil,nil,["1","two","three","four","5"]).tabWidth_(70).tabHeight_(13).tabCurve_(3); 

)

super tall and clear

(

TabbedView(nil,nil,["1","two","three","four","5"]).tabWidth_(70).tabHeight_(30).tabCurve_(3); 

)




Change History:

Aug 27, 2007 :  code optimized; instanceVar tabPosition. Version 1.0;

Aug 24, 2007 :  small code optimizations Version 1.01;

Aug 23, 2007 :  fixed small bug when bounds=nil  Version 1.02;

Aug 30, 2007 :  added scroll option. Convenience new methods can now  take arguments of form arg:value  Version 1.03;

Sep   2, 2007 :  FlowView contents will now reposition in real time if tab  position is changed. tabPosition getter. Version 1.04;

Tabs can switch during drags(cocoa only); 

Feb 12, 2008 :  relativeOrigin variable added to adjust to new SCCompositeView behavior. Swing compatibility. Version 1.10;


Feb 16, 2008 :  Version 1.11;  Swing themes adjusted to use no transparency.  

deprecated: newRGB and newRGBLabels ;

use new methods: newColor and newColorLabels instead.

swingFactor defaults to 7 (integers work better than floats,

Feb 19, 2008 :  Version 1.12;  

focus_() deprecated;   use  focus(index) instead. 

focused added.

Feb 19, 2008 :  Version 1.13;  

focused removed and changed to activeTab.

All variables that had a double s in "focussed", changed to singel s;

Feb 20, 2008 :  Version 1.14;  Fixed returned tab on add and insert methods  


Feb 20, 2008 :  Version 1.15;  added font variable. other bug fixes  


Feb 26, 2008 :  Version 1.20;  added followEdges option.  

July 9, 2008 :    Version 1.21;  updates for SC3.21