by Harry Hooie
| ![]() |
SmartSplitter is a cross-platform open-source control splitter class for REALbasic 5 or greater. The SmartSplitter control allows the user to resize other controls contained in the window as desired. It can automatically attach nearby controls thus achieving full functionality with NO coding and NO binding! SmartSplitter is developed for and tested on Linux, Mac OS 9, Mac OS X, and Windows 98/2000/XP.
SmartSplitter began like so many other classes do - as a simple crappy class in an early crappy project. But as I used this divider thingy in more of my projects, I gradually added in smarts until so great the intellect of this amazing class, I felt obliged to spend the extra effort to simplify it, clean it up, and make it more accessible.
IMPORTANT: If your window is to be resizable, a call to each SmartSplitter's behave method needs to be added to the parent window's Resized event (AND to the Resizing event if the window is set to LiveResize) see how | ![]() |
The SmartSplitter class is provided free for all to use. However, I do maintain ownership of SmartSplitter. You are free to redistribute the source code. If you distribute it as a standalone class, please include this documentation with it. If you distribute source code containing SmartSplitter, you do not need to include this documentation. There is no requirement to credit me in your program for using SmartSplitter.
If you make any code improvements, you are welcome to submit them, and I will try to incorporate them in the next update so that everyone using SmartSplitter can benefit.
If you use SmartSplitter in a project that generates actual profit (unlike any of mine;) or in a project for your work, you may feel compelled to offer compensation for the benefit it provided. Any monetary gift of thanks would be appreciated and would encourage continued development and support of this and other projects. To donate, go here.
First add the SmartSplitter class to your project by dragging the "SmartSplitter" folder into your project window.
To add a SmartSplitter to one of your project windows, add a canvas to the window and change the canvas's Super property from "Canvas" to "SmartSplitter". (or drag the SmartSplitter class from Project Controls onto the window) Then resize it so that it covers the area between the controls you wish to be adjustable.
If the splitter's height is greater than its width, it will act as a vertical splitter and look for controls to the left and right. Otherwise it will act as a horizontal splitter looking for controls above and below. Controls with edges within 5 pixels of the edges of the splitter will automatically attach unless you command otherwise.
All controls you wish to adjust with the splitter should be position-locked (i.e. LockLeft, LockTop, etc.) so that they resize correctly with the window - even if the window is not going to be resizable.
If you are going to set the SmartSplitter to DisableLiveDrag, its control order should be greater than that of the attached controls so that it will appear above the controls during the drag. Otherwise, for live dragging, set the SmartSplitter to be behind any attached controls so that in case one of those controls is showing a focus ring, it will not be visibly clipped in composite windows.
The SmartSplitter folder also contains the CanvasSmartSplitterDebugger canvas class which may be used to better see what SmartSplitter is doing.
If your window is to be resizable, add a call to each SmartSplitter's behave method to the parent window's Resized event:
Sub Resized()
SmartSplitter1.behave
SmartSplitter2.behave
End Sub
And also to the Resizing event if the window is set to LiveResize:
Sub Resizing()
SmartSplitter1.behave
SmartSplitter2.behave
End Sub
The behave method keeps the SmartSplitter locked to its MinLimit and MaxLimit if it was previously locked and adjusts its proportions if StayProportional is set to true. (see Setting SmartSplitter properties)
For most common cases, the above is all you will need to do ! |
Controls are determined when first attached whether they need to be moved, resized, or both.
SmartSplitter can only determine control behaviour correctly when the controls being attached are first position-locked so that they resize correctly with the window. So if you are having problems, resize your window and see if your controls are resizing as they should. |
SmartSplitter also looks at the control's class, orientation, and settings to determine whether it should be resized. For example, a EditField or StaticText based control would never be set to resize vertically if MultiLine = False.
An embedded control gets set differently since REALbasic is supposed to move it with the parent control. An embedded control set to LockLeft will be suggested to resize by a vertical splitter (LockTop by a horizontal) since it will assume the parent control is being resized as well.
But invariably, SmartSplitter will sometimes guess wrong no matter what you do, so...
To save the splitters position to restore later, such as with preferences, save the SmartSplitter's position or proportion method value:
i = SmartSplitter1.position ' dim as integer
or
x = SmartSplitter2.proportion ' dim as double 0 ≤ x ≤ 1
All references to position (Min & Max) and proportion are from left to right with vertical orientation and from top to bottom with horizontal orientation.
Restore the splitter's (and its attached controls') position using the companion method - setPosition or setProportion (see Setting SmartSplitter properties for more details):
Position should be referenced as an integer. Proportion must be referenced as a single or double - double is preferred as that is how it is referenced internally. Proportion should be equal or greater than 0 and less than or equal to 1.SmartSplitter1.setPosition = i ' as integer
or
SmartSplitter2.setProportion = x ' as double
These 3 methods are the meat of SmartSplitter.
If there are additional controls that should be impacted by the splitter, then the following should be added to the sub's Open method:
Sub Open()
me.attachNearbyControls ' (if you want it to auto-attach what it can)
me.attach otherControl1
me.attach otherControl2
me.attach otherControl3
End Sub
Attempts to attach a control that has already been attached will be ignored.
The attachNearbyControls method is called internally in the SmartSplitter super AFTER your SmartSplitter sub's Open method is called - but ONLY if attach has not yet been called. This is why if you want to auto-attach, me.attachNearbyControls must be called before any additional controls are attached.
To attach all your controls manually, leave out the me.attachNearbyControls and use me.attach to attach them.
When a control that commonly has embedded controls (TabPanel, PagePanel, etc.) is attached, all its embedded controls are recursively attached as well. If you want to manually attach embedded controls as well, set doNotAttachEmbeddedControls = true before you attach any controls that contain embedded controls. Controls that are searched for embedded controls are determined in the controlCommonlyHasEmbeddedControls method.
Only controls whose superclass is a RectControl can be attached. In REALbasic 5, the Line Control is a RectControl, but since it ignores the Left, Top, Width, and Height properties, it would have required additional code that was likely to break in a future version of REALbasic. So SmartSplitter will ignore any attempts to attach a Line Control. If you want the splitter to move/resize a Line Control, you will have to put the appropriate code in that SmartSplitter sub's Moved method.
Controls MUST be attached before attempting to modify their properties.
The most commonly used will be setAttachedControlShouldMove, setAttachedControlShouldResize, and setAttachedControlNormallyVisible.
Example of changing control properties in the splitter's Open method:
Sub Open()
me.attachNearbyControls
me.setAttachedControlShouldMove BevelButton1, true
me.setAttachedControlShouldResize Canvas1, false
me.setAttachedControlShouldCenter BevelButton3, false
me.setAttachedControlMinSizeVisible MoviePlayer1, 64
End Sub
There may be certain configurations of embedded controls inside of embedded controls that cannot be controlled correctly by adjusting the move and resize properties. Those controls will require the appropriate code in that SmartSplitter sub's Moved method.--- Using the IDE "Properties" window ---
The following additional properties should be available for SmartSplitters in REALbasic's "Properties" widow if you are using REALbasic 4.5 or greater:
| ![]() |
--- Using Code ---
I recommend attaching all controls before setting SmartSplitter "Limit"-related properties using code since "Limit"-related values will likely auto-adjust as controls are added.
The CanvasSmartSplitterDebugger canvas class may be used to display debugging information while one or more SmartSplitters are adjusted. It will display the minLimit, MaxLimit, minLimitOffset, and maxLimitOffset values of a SmartSplitter as it is being dragged. It will also draw a red rectangle around all attached controls each time they are adjusted - including when the splitter's behave method is called. Invisible controls are denoted by a red X that spans the red rectangle.
To use, add 1 CanvasSmartSplitterDebugger canvas anywhere in the window.
Then check the Debug property in each SmartSplitter's "Properties" widow that you wish to debug. (or call setDebug(true))
Note that when not debugging, the canvas is not used so no extra memory is consumed.
You may set SmartSplitter.enableDebugCanvasCode constant to FALSE in the IDE to completely skip all
debug code. Also, if you delete SmartSplitter's debugCanvas property, CanvasSmartSplitterDebugger will no longer be required in your project.
Version 1.3.2
Version 1.3.1
Version 1.3
Version 1.2.2
Version 1.2.1
Version 1.2
Version 1.1
Legal mumbo jumbo | ![]() |
SmartSplitter is provided "as is" without warranty of any kind, either expressed or implied. The entire risk arising out of use or performance of SmartSplitter remains with you. While the SmartSplitter source code itself may not be sold or distributed for profit, the SmartSplitter source code MAY be included with other software, services, publications, or products which are sold or distributed for profit as long as this documentation is included with it. Harry doesn't mind if he doesn't make the scene. He's got a daytime job, he's doing alright. |