0084: Notebook VIII – Child Widgets

Accessing any child widgets we’ve stuffed into Notebook pages—for loading or saving a document, for instance… or changing/updating the tab label—takes a bit of prep that you might not expect, but by relying on the Notebook’s in-built tab managing system, it’s relatively straightforward.

Accessing the Widget in the Page

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

Setting the text in a TextView is something we’ve seen before in the first Notebook demo and—cherry picking statements from the preamble and constructor—goes something like this:

TextBuffer textBuffer;
string content = "Now is the English of our discontent.";

textBuffer = getBuffer();
textBuffer.setText(content);

Once everything’s prepped, a call to setText() does it. But what about the other way around, accessing the content of a specific Notebook page for the purposes of saving it?

Retrieval of Page Content

No matter what type of Widget we stuffed into our Notebook page, the process is the same:

  • ask the Notebook for the current page with a call to getCurrentPage(), and
  • get a pointer to that page’s child Widget using getNthPage().

Note that we have to cast the result of getNthPage() because Notebook doesn’t keep track of which type of Widget we stuffed in there. So if we used something more elaborate than a single TextView widget… say a Grid with five Entrys… and we wanted to access them, we’d have to get a pointer to the Grid and then access the Entrys using the Grid’s getChildren() function.

But in our current example, once we’ve got a pointer to the TextView, we get the text by:

  • grabbing a pointer to the TextBuffer with TextView.getBuffer(), and
  • yanking out the text with TextBuffer.getText().

And once you’ve got that, saving the text is a matter of passing it along to an appropriate function.

The PageInfoButton

But for this demo, we won’t go into saving. Instead, we’ll just prove to ourselves that we’ve got access to everything by adding another Button to our interface and hooking up a callback that echoes all pertinent information to the command prompt window. The PageInfoButton class, complete with callback, looks like this:

class PageInfoButton : Button
{
	string _buttonLabel = "Page Info";

	MyNotebook _myNotebook;

	this(MyNotebook myNotebook)
	{
		super(_buttonLabel);
		_myNotebook = myNotebook;
		
		addOnClicked(&onClicked);
				
	} // this()
	
	
	void onClicked(Button button)
	{
		int currentPage = _myNotebook.getCurrentPage();
		TabTextView tabTextView = cast(TabTextView)_myNotebook.getNthPage(currentPage);
		Label tabLabel = cast(Label)_myNotebook.getTabLabel(tabTextView);
		
		writeln("currentPage position in the Notebook tabs array:", currentPage);
		writeln("tabLabel: ", tabLabel.getText());
		writeln("tabTextView contents: ", tabTextView.getBuffer().getText()); 
		
	} // onClicked()
	
} // class PageInfoButton

And in the onClicked() callback, you can see the steps outlined in the previous section. For completeness sake, we also:

  • grab a pointer to the tab’s label, and because we know it to be a Label Widget (that’s with an uppercase ‘L’) we cast it as such, and
  • from there, we can use Label.getText() to retrieve the text visible in the tab.

So, now we know how to set/get text from a TextView embedded in a Notebook page as well as how to get text from a Notebook tab. And we also know how to initialize the tab text when we’re creating the Label, but…

What if we wanna reset the tab text programmatically?

The SetTabTextButton

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

This we’ll do from another callback. Setting up the Button is exactly the same, so I won’t go over it here, but let’s look at the SetTabTextButton’s callback:

void onClicked(Button button)
{
	TextIter startIter, endIter;
	int currentPage;
	TabTextView tabTextView;
	TextBuffer textBuffer;
	Label tabLabel;
	string newLabelText;
		
	currentPage = _myNotebook.getCurrentPage();
	tabTextView = cast(TabTextView)_myNotebook.getNthPage(currentPage);
	textBuffer = tabTextView.getBuffer();
	tabLabel = cast(Label)_myNotebook.getTabLabel(tabTextView);
		
	if(textBuffer.getSelectionBounds(startIter, endIter))
	{
		newLabelText = textBuffer.getText(startIter, endIter, false); // false: do NOT include hidden characters
		tabLabel.setText(newLabelText);
	}
		
	writeln("currentPage position in the Notebook tabs array:", currentPage);
	writeln("tabLabel: ", tabLabel.getText());
	writeln("tabTextView contents: ", tabTextView.getBuffer().getText()); 
		
} // onClicked()

Rather than have the Button pop open a dialog with a text Entry and all the related dialog Buttons that go along with gathering text from a user, I opted instead for a simpler approach for this demonstration.

Here’s how it works… The user selects a chunk of text in the TextView. Then a click on this button grabs the selected text and stuffs it into the tab label. Here are the steps:

  • get the current page/tab,
  • get a pointer to the TextView and, after that, its TextBuffer,
  • grab a pointer to the tab’s label (and in this case, it’s a lowercase ‘l’, so not a Label Widget),
  • check to see if some text is selected in the TextView and, if it is…
  • create a string from the selected text, and
  • call setText().

The rest is the same as what we had in today’s first demo.

Conclusion

So, now we’ve got a handle on Notebook page/tab input/output and that’s just about as far as we’ll be going for now. Next time, we’ll jump back into the Nodes-n-noodles series.

Until then, have fun.

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