0078: Notebook II – Multiple Tabs, Reordering & Image Tabs

A single tab in a Notebook has limited value, so today we’ll start by adding more. Then we’ll look at how to turn on the reorder mechanism, and finish off by replacing the Label contained in the tab with an Image.

Because the CSS we worked with last time gave us fully-visible tabs, let’s continue with that for now.

Multiple Tabs

Results of this example:
Current example output
Current example output
Current example terminal output
Current example terminal output (click for enlarged view)

Not much has to change to have more tabs. Just add more strings for tab names, more Labels, and more TextViews… or whatever you’re cramming in there. Your class preamble might look like this:

CSS css; // need to see tab shapes against the bg
PositionType tabPosition = PositionType.TOP;
Label tabLabelOne, tabLabelTwo, tabLabelThree;
string textOne = "Tab One", textTwo = "Tab Two", textThree = "Tab Three";
TabTextView tabTextViewOne, tabTextViewTwo, tabTextViewThree;

And the constructor might resemble this:

this()
{
	super();
	setTabPos(tabPosition);
	css = new CSS(getStyleContext());

	tabTextViewOne = new TabTextView("Now is the witness of our discontinent.");
	tabLabelOne = new Label(textOne);
	appendPage(tabTextViewOne, tabLabelOne);

	tabTextViewTwo = new TabTextView("Four stores and seven pounds ago...");
	tabLabelTwo = new Label(textTwo);
	appendPage(tabTextViewTwo, tabLabelTwo);

	tabTextViewThree = new TabTextView("Help me open yon cantelope.");
	tabLabelThree = new Label(textThree);
	appendPage(tabTextViewThree, tabLabelThree);
		
} // this()

Now, let’s move on to…

Reordering Tabs

Results of this example:
Current example output
Current example output
Current example terminal output
Current example terminal output (click for enlarged view)

This is easy, too. All we have to do is add one line each time we add a tab:

setTabReorderable(textViewOne, true);

Which means our Notebook class might look like this:

class MyNotebook : Notebook
{
	CSS css; // need to see tab shapes against the bg
	PositionType tabPosition = PositionType.TOP;
	Label tabLabelOne, tabLabelTwo, tabLabelThree;
	TabTextView textViewOne, textViewTwo, textViewThree;
	
	this()
	{
		super();
		setTabPos(tabPosition);
		css = new CSS(getStyleContext());

		textViewOne = new TabTextView("Now is the witness of our discontinent.");
		tabLabelOne = new Label("Tab One");
		appendPage(textViewOne, tabLabelOne);
		setTabReorderable(textViewOne, true);

		textViewTwo = new TabTextView("Four stores and seven pounds ago...");
		tabLabelTwo = new Label("Tab Two");
		appendPage(textViewTwo, tabLabelTwo);
		setTabReorderable(textViewTwo, true);

		textViewThree = new TabTextView("Help me open yon cantelope.");
		tabLabelThree = new Label("Tab Three");
		appendPage(textViewThree, tabLabelThree);
		setTabReorderable(textViewThree, true);
		
	} // this()
	
} // class MyNotebook

No big deal.

You may wonder what would happen if you set some tabs to be reorderable while leaving others as is. It turns out, the non-reorderable tabs still move around, but only to get out of the way of the other tabs. Rather than actually being unmovable, they become passive-resistant, refusing any direct manipulation, but giving in if another tab needs it to move aside.

Now, let’s look at what can be done to give tabs a bit more visual appeal.

Images in Tabs

Results of this example:
Current example output
Current example output
Current example terminal output
Current example terminal output (click for enlarged view)

Here’s the breakdown of what needs to be done:

In the preamble, we declare an Image widget for each tab:

Image tabImageOne, tabImageTwo, tabImageThree;

In the constructor, we instantiate them:

tabImageOne = new Image("images/green-man.png");

And append each Image to the tab just like we would a Label:

appendPage(tabTextViewOne, tabImageOne);

Here’s how the MyNotebook class might look taking this approach:

class MyNotebook : Notebook
{
	CSS css; // need to see tab shapes against the bg
	PositionType tabPosition = PositionType.TOP;
	Image tabImageOne, tabImageTwo, tabImageThree;
	TabTextView tabTextViewOne, tabTextViewTwo, tabTextViewThree;
	
	this()
	{
		super();
		setTabPos(tabPosition);
		css = new CSS(getStyleContext());

		tabTextViewOne = new TabTextView("Now is the witness of our discontinent.");
		tabImageOne = new Image("images/green-man.png");
		appendPage(tabTextViewOne, tabImageOne);
		setTabReorderable(tabTextViewOne, true);

		tabTextViewTwo = new TabTextView("Four stores and seven pounds ago...");
		tabImageTwo = new Image("images/yellow-man.png");
		appendPage(tabTextViewTwo, tabImageTwo);
		setTabReorderable(tabTextViewTwo, true);

		tabTextViewThree = new TabTextView("Help me open yon cantelope.");
		tabImageThree = new Image("images/whisk.png");
		appendPage(tabTextViewThree, tabImageThree);
		setTabReorderable(tabTextViewThree, true);
		
	} // this()
	
} // class MyNotebook

And, voila, we’ve got reorder-able custom tabs.

Conclusion

Another thing I got to wondering about while preparing these demos was this: is it possible to draw a more elegantly-shaped tab without resorting to an Image? As it turns out, the answer is yes, but there is a gotcha to consider. We’ll talk about that next time when we get to some real roll-up-your-sleeves customization.

Until then…

Comments? Questions? Observations?

Did we miss a tidbit of information that would make this post even more informative? Let's talk about it in the comments.

You can also subscribe via RSS so you won't miss anything. Thank you very much for dropping by.

© Copyright 2023 Ron Tarrant