Comming Soon Scrollable Textboxes

Feb 17, 2009 at 1:33 PM
I recently checked in some changes that add scroll bars to the project and I wanted to put them to use to make a scrolling text box. I've been working on that code for a few days now, and I've come to realize that horizontal scrolling is just going to be a huge pain, without much benefit. let me rephrase that. With fixed width fonts horizontal scrolling wouldn't be so bad, but once you throw in variable width fonts, it gets a lot harder.

What really sealed the deal to no support horizontal scrolling is that any text that you have scroll the window left and right to read is just a total pain for the reader. So instead I am going to concentrate on vertical scrolling only with word wrapping. That should make things a lot easier to implement since it should work with both fixed and variable width fonts. plus I won't have to do weird cropping when half a letter fits into left edge of the screen.

If anyone has a really strong case for supporting horizontal scrolling text boxes, make a case and I may add it but, it seems to me that at this time its not going to be worth it.
Feb 19, 2009 at 3:58 PM
I ran into an interesting problem while making the scrollable text box that put things back by about two days, but I've found the problem, so here is an explanation and all the nerdy details. If you've noticed I creates scroll bars first with the assumption that I would be able to re-use the stand alone scroll bars in other more complicated components. This worked nicely, since I was able to declare and initialize a VScrollBar in the new component. By Adding it to the new components children I was able to get it draw and receive user input with minimal fuss. The trouble came about when I needed to respond to the scroll bar's ValueChanged event. During the new component's constructor I was setting the event handler, but when the code that should have raised the event ran, the event handler was no longer assigned. Everything else about the control was set, all of its properties were just as I had made them in the constructor. I was baffled. I proceeded to bark up the wrong tree thinking it was something to do with the event code.

At some point I decided that copy of the scrollbar inside the new text component must have been getting copied. I added a constructor to the scroll bar and set a breakpoint in it. When I ran the program I was able to confirm that more than one scroll bar was getting created. The first time it was created was by the new text component constructor exactly as expected. The second time was during the loading of the GUI content. This suprised me.

After some investigation I was able to determine what was happening. When the project was built, the content serializer would load up my XML file that defined the GUI. This would cause and instance of the new text component to be created, which in turn created an instance of the scrollbar. The scrollbar got added to the text component's children as I had written the constructor to do. This instance of the GUI, complete with scrollbar was then passed to the content writer, which wrote out new XNB files complete with an erroneous scrollbar which was not part of the original XML file. Now when the project was run, the XNB file was loaded, and when it got to the new text component, an instance was created, the constructor created a new scrollbar and set its event handler. The the content read proceded with reading the rest of the XNB file, where it found the erroneous  scrollbar and loaded it, overwriting the one that had been created in the constructor. This newly loaded scrollbar had all the right properties since it had been written to the XNB file with all the right properties, but without the event handler. The result that by the time the code ran to process my click event, the component had been replaced with an imposter.

So to fix this, I've had to add some new functionality to the the base Component Class, Ive added a new property to it called WriteToContent which defaults to true. This is used by the content writer to decide if the child component should be included in the XNB file. For instances of components defined in XML this will be no different since they should be written. Where this meant to be used is by composite componets like my new text component. The new text component's constructor sets WriteToContent to false for its scrollbar, and viola the scrollbar is not included in the XNB content file. At this point there was one last change to make, The component's read content code had to be changed so that any child components that were read from the XNB would be added to any child components created programatically. In the end it turned out to be a rather small change in terms of lines of code changed to fix this, but It does solve a huge problem in creating composite controls, and now that this is resolved, it should be a lot easier for me to create some additional controls later on like the listbox, and combo box, since the list box will contain a scroll bar, and the combo box will contain a list box as well.

At this point I am going to move on with the text scrolling and multiline editing. Hopefully this will result in a new release in the next few days.