Copyright © 2008, 2009 Arndt Roger Schneider
The RTL based option creator is used
to instantiate the template gstripes with a
Tk Window. The used creator window must have a
-class
property.
Acceptable Tk Windows are: toplevel for floating windows, and frame for embedded windows.
»stripesCommand« is used in combination with »adjustCommand«. These two properties allow to replace the default stripes with a custom variant. »stripesCommand« is responsible to fill the background of the stripes window, whereas »adjustCommad« realigns the background after a resize event has happened.
A predefined »stripesCommand«, called »nilstripes«, is provided with gstripes. Use »nilstripes« to gain the best performance.
Example A.22. Use nilstripes for high Performance
# Add this to your code or the XRDB resource # file, for a plain coloured background: option add *stripes.stripesCommand nilstripes option add *Goolbar.stripesCommand nilstripes ... ;# or ... Resource file: *stripes.stripesCommand: nilstripes *Goolbar.stripesCommand: nilstripes
»adjustCommand« realigns the Gstripes background in response to a Configure event. A typical adjust action is to redraw the focus frames.
Example A.23. An adjustCommand for Rtl_gridwin
option add \ *Rtl_gridwin.stripes.adjustCommand \ gwadjust proc gwadjust {base canvas} { adjustCommon $base $canvas set gridwin [winfo parent $base] # Force to redraw the focus ring: if ![string first $gridwin [focus]] { $gridwin focusIn } }
Needed for TkPath lower before version 0.2.7. »repairCommand« was called in response to missing gradients. This could happen with TkPath whenever multiple Tk Window hierarchies, using TkPath, existed inside a single application.
Issue is solved and »repairCommand« is no longer necessary.
static property.
Boolean value, default is »1«, on.
»touch« controls whether or not the created Gstripes window interacts with hijacked windows or not. When »touch« is set to 1, the window Z-Order is altered. Event handlers are registered between Gstripes and hijacked windows.
A Gstripes window, where touch is disabled (0), is used as a pre-print preview for an already striped dialog.
Gstripes creates white space. A striped window –a dialog– uses a gstripes window for rendering its background.
The gstripes created white space can be enriched with various elements such as background frames, contours , images, vector graphics, labels, messages checkbutton, radiobutton, button, menubutton, menus, menubars and groups .
Gstripes is also used for creating AQUA® like focus frames, which fade into white space. This is used in the Runtime Library templates rtl_combobox, rtl_gridwin; and the gestalt items template gistbox. Three focus functions are present: »gstripes::focusframes«, »gstripes::focuspathes« and »gstripes::focuscircles«. TkPath is required for using focuspathes and focuscircles.
White Space is created by the »gstripes::stripes« and »gstripes::adjust« functions. Both functions can be substituted by defining the option database entries »stripesCommand« and »adjustCommand«. Thus white space of any kind can be used within gstripes.
Controls, passive such as label an message, active such as button, radiobutton, ... are absorbed by gstripes through hijacking. A hijack function exists for each supported control such as »hijackbutton« for »Button« controls. These hijack functions are not to be used directly but rather through the general function »hijackwindow«.
A special gstripes feature are »groups« and »contours«. A contour is created from a combination of overlapping »frame« windows. Boolean operations (+ and -) can be used for contours. Holes are not supported.
groups are created from active controls: button, menubutton, radiobutton and checkbutton. radiobutton and checkbutton must not have an indicator for being used as part of a group.
A somewhat special case are striped menus. Menus are themselve white space but treated by gstripes as an active control. radiobutton and checkbutton, inside of menus, are rendered identical to their indicator based dialog counterpart.
Menu hijacking is only possible under X11.
The radiobutton and checkbutton indicators can be replaced with a »vector«. This vector is defined for the individual radiobutton, checkbutton via the option database entry »indicatorVector«.
Example A.24. Indicators
option add *Grefadvance$w(6).indicatorVector {gstripesvector::triangleButton} option add *Grefadvance$w(8).indicatorVector {gstripesvector::triangleButton}
The above Example A.24, “Indicators” , from the »grefadvance« template, replaces the standard checkbutton indicator –a checkmark – with a triangle button. This »triangleButton« is used to represent visual disclosure. The vector »triangleButton« also contains a »focusframe« element for highlighting.
The option database entry indicatorVector is also applied on striped menus, but cannot being used for an individual menu entry–menu entries do not have access to the option database.
TkPath
TkPath 0.2:
Most –if not all– of gstripes effects require an elaborated graphical subsystem. The chosen subsystem is TkPath, which must have version 0.2.4, better higher than 0.2.7. Which also means Tk 8.5 is mandatory, too – sorry for this. Under X11 CAIRO, too.
TkPath 0.3.0 and caché:
There are changes necessary for using TkPath 0.3.0; these changes are ➊ import of tkp::canvas into the gstripes namespace and ➋ an entirely new caching strategy for gradients.The module gcache is used for this new caché strategy. Originally, gcache used a global strategy for caching, this mechanism is changed to ➌ a local base variety. Another issue though: ➍ the used caché must be deleted whenever the gstripes window is ➎ destroyed –the caché must not survive the associated window.
Gradients:
TkPath 0.3 and 0.2 gradients are partly incompatible. Gstripes will support global gradients from TkPath 0.2 as long as possible. TkPath 0.2 can be used under Tk 8.4 and moving entirely to TkPath 0.3 means to abandon Tk 8.4, too –which I don’t want right now. This means there are four (4) different »gradient« varieties. The TkPath 0.2 starts with a »fixme« to warn about such duplications. The alternating versions are dedicated to AQUA® or X11, respectively.
Open Issues
How is it possible to alter the selectColor for menubutton, button, checkbutton and radiobutton when a dialog is deactivated?
Replacing »Control«, »Alt«, »Meta«, »Shift« inside of menu short-cuts does not work. Unicode related issue in Tk. Implemented but disabled.
A Window created through the gstripes command exposes various functions. Using these functions has the following general form:
pathName option ?arg arg ...?
PathName is the same as the window path name. Option and the args determine the exact behavior of the command. The following commands are possible for this window:
Returns the current value of the configuration option given by option. Option may have any of the values accepted by the gstripes command.
Query or modify the configuration options of the window. If no option is specified, returns a list describing all of the available options for pathName (see Tk_ConfigureInfo for information on the format of this list). If option is specified with no value, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no option is specified). If one or more option-value pairs are specified, then the command modifies the given window option(s) to have the given value(s); in this case the command returns an empty string. Option may have any of the values accepted by the gstripes command.
Cover the stripes window with a semi-transparent sheet. To indicate that this dialog is no longer accessible. See also goolbar, activate. See Open Issues.
Trace handler for checkbutton and radiobutton kind of controls.
The variable might being used as part of a radiobutton group, in which instance the event handler must be used to notify all related responders for this variable. The unconventional Expose event is being used for this purpose.
Test whether the expected gradient was destroyed. Return 1, when a gradient is expected but not available.
Does modify the coordinates of a group. A group is defined by its outer items. The inertia is drawn from the individual item. First and last are used to draw the control itself. Both require new focus frames, too.
The complexity of groups exceed the ability of »modifyGroup« Using »modifyGroup« will yield a disected group.
Consequently group modification is also removed from the »hijackwindow« function. Which leaves the direct operation from the general event-handler (configure). Internal modifications have thus to be accompanied with a hijackgroup call, to reflect those changes inside the group presentation.
Changes the visual state of the item to resemble a pressed button. The way how pressed is done depends on the state model selected for the »window«.
Applies for menubutton, button and checkbutton, radiobuttons inside of »groups«.
A Group is a collection of button, checkbutton and radiobutton treated as a single control. The outer elements do receive rounded corners while the inner elements are square. Images (and later compound???) are allowed for grouped elements! Images are left alone.
Pimage, which provides scaling, is to limited anchor-wise for being used, here. In addition, activeImage & disabledImage are definable from the option database. Scaling is a gut turning thing for groups anyway. Using the normal image with activeImage and disabledImage is the better way for doing this.
In cases when this button is part of a group and if it is the first one (path1) it is required to move the caption with hl and borderwidth to the right. Ditto for the last item, but to the left.
For groups, not managed by their parent window, an »update idletask« call is needed. In order to get the proper (real) position! This is specified for the first group element, which need not to be the »groupleader«. Option database entry »update« set to »1« (true) causes it.
See also the revision notice inside the commentary for »modifyGroup«.
Realign the items inside of a group, so that text and space is even distributed among the group members.
Call the »repairCommand« when registered And report the repair result back to the caller.
Currently only used by stripesmenu. Intended to repair selection failures.
RELATED TO A BUG INSIDE TKPATH 0.2.4‥0.2.7, NOT NEEDED ANYMORE, ISSUE SOLVED.
...from leave. Left is called in response to an enter event. That is when another control receives the input focus left is executed. This delay is needed in order to prevent flicker effects with layered graphical objects –belonging to the same control. left may also being triggered due to a after timer event.
Do call adjust each time the window gets visible. Only the stripes should be aligned, not the hijacked or individual stuff. Also the modulo value must be definable. As "moduloY"" and "moduloX" inside the option database.
See also: adjustCommand.
Stripes created by »gstripes« have an additional Tag »gstripes«, this tag is used here instead of »stripes«. This allows combinations of stripes.
Note 04/17/2008 - 21:46 : Signature has to be identical to foreign adjust commands. Otherwise an adjust error must ensue inside the goolbar- –solves the ».back« problem, too.
See description for »borders«.
See also »leftborder«.
Extended with local caché strategy, needed by tkpath 0.3.0.
A control may feature a shadow. Shadows are only allowed for groups, menubuttons, buttons if the control in question has rounded corners and shadow is activated for it.
See hijackprototype, hijackgroup and modifyGroup.
Create the bidirectional bindings for the »window« and its stripes imposter –identified via »tags«.
An »unmap« event is being added, unmap is used to remove any resedue of that window from gstripes. »unmap« is activated by the ».unmap« option database entry set to 1 (true).
Normally no unmap should being monitored for a given window –is unnecessary. Only windows with visual disclosure shall use this feature.
Motion event is cruical for menubutton, apparently selecting the internal menu structure originates from the menubutton and not from the menu. Hijacking the motion event lay lead to a deadlock inside of global grabed dialogs.
Creates a striped menu from the »menu« in question. »menu« must be the real window, that is a clone when it is part of a menubar. hijackmenu iterates over the menuentries and creates striped representations for each entry.
Draws a Radio indicator. This is a circle using an radial gradient. If »window« is selected, then the selecColor is used for the indicator background and an opaque inner circle is drawn to indicate selection.
Radio and Check- indicators are only allowed for stand alone controls. In truth they must have an indicator.
Local caché strategy using gcache.
Replacement for »hijack« see description at »hijack«. The procedure »alienhijack« allows the hijacking of alien templates, that is the the stripes window need not to be part of the templates hierarchy.
Test whether or not the item is selected. The procedure returns false if the associated variable does not, yet, exist.
Externalize the hijacking of images. can be used inside hijackprototype and label.
This code is currently unused (no need). Has to be used directly.
Formats the proper event handler for the Map Event. Hijacked windows must be reevaluated whenever the template is remapped.
Hijack a menu entry of »menu« given by it's index »i«. The Height »height« is used to position the text where it belongs.
Used by »stripesmenu«.
Shift-Option-Command-x There is some trouble with UTF-8, CAIRO and tkpath, therefore not used, yet.
Default glyphs from »gestalt.ttf«:
option add *Menu.keyboardfont {gestalt} option add *Menu.controlkey b option add *Menu.optionkey d option add *Menu.shiftkey r
Default glyphs from AQUA®:
option add *Menu.keyboardfont {apple symbols} option add *Menu.controlkey ⌃ option add *Menu.optionkey ⌥ option add *Menu.shiftkey ⇧
Not implemented, yet:
option add *Menu.deletekey ⌫ option add *Menu.Upkey ↑ option add *Menu.downkey ↓ option add *Menu.leftkey ← option add *Menu.rightkey → option add *Menu.homekey ↖ option add *Menu.endkey ↘ option add *Menu.pageupkey ⇞ option add *Menu.pagedownkey ⇟ option add *Menu.cascade ▸
Creates a indicator for the item »i« inside of »menu«. The indicator is placed in a rather complicated fashion. First it is created off-screen and later –when the menu is striped– moved on-screen. That is why »tx« –caption x-position– is used here.
Note 01/30/2009 - 10:39 : Vectors can be defined for checkbutton and radiobuttons. There are two option database entries for this:
* radioIndicator * checkIndicator
Both work per menu and not on an entry! This differes from indicatorVector for gstripes windows. –A technical limitation.
The official way for hijacking a window, group or contour. The template related functions –hijack, stripes and substripes– do also use »hijackwindow«. Be careful when using it! It should be used in response to a <Configure> and/or <Map> event for the same dialog.
The over all design will follow Aqua & Tk. sunken / raised for the indicator. Highlight around the indicator. The indicator receives the background color / selectColor. The text will not feature a background, but partakes in the active state.
Event handler isolated. Sets the previous colors back to their default values --through menuupdate.
Needed, because the event can occur after the stripes window and the menu have been destroyed.
Draws a series of focus frames. These technique is mainly used under AQUA®. The inner focus frames are also darker than the outer frames.
Option Database property »highlightFraction«, highlightFraction makes subsequent colors lighter or darker; default is »90« meaning 10 percent darker.
Does hijack messages or labels. »window« is the pathname to the message window.
Creates a »text« entry inside the gstripes canvas window. Position and size are determined by »x, y, wd and hg«.
»top« and »middle« alignment is best for messages. The -linespace and -ascent values reported by font metrics are usually wrong. »top« alignment avoids errorneous SVG output; –10/20/2008
See description for »borders«.
»left« and »right« partake in the local caché strategy demanded by tkkpath 0.3.0.
Hijacks a label or message window. These window must be a sibling to the stripes window. This version is intended for template based dialogs ... use the lower level functions for dialogs based on another model.
Accepted classes are Frame, Button, Checkbutton, Radiobutton, Label, Message and Menubuttons. Frames can be arranged in contours – {28 - 29 + 45}. Button, Checkbutton, Radiobutton and Menubutton can be grouped – {30 31 32}.
A group may contain multiple classes, but not a frame; a contour only frames.
Code moved to alienhijack.
Modify the associated canvas item in response to a Configure event for the stripes parent window. This may alter the geometry of the associated window.
»moveHijack« might be called for an unmaped window and must fail! A verified is used to get over it gracefully.
Hijack a frame and send the hijacked element to the background–behind stripes.
Experimental hijacking a button when tkpath is present ... doesn't make sense for vanilla Tk, hence not implemented for tk.
Create a tkpath gradient from the background color and draw a prect rectangle around it.
Image is allowed for a stand alone button. See also the comment for hijackgroup concerning images. The image code will be subjected to changes in the future; handle with care!
Creates borders to the left and right side of buttons, menubuttons and groups featuring radius- An element without a radius does not receive a border, the same applies for checkmark and radio- mark. Disable borders from the option database by defining »borders: 0« for the window in question.
Creates a gstripes window. Recommended, use the »stripes« function for a template to manage stripes. The »stripes« function then creates a gstripes window.
Custom destroy. This is a special destroy, needed to circumvent default-destroy breakup. A messageBox is used in this case and thus default-destroy won’t be performed.
THIS PROCEDURE IS GENERALLY NOT NECESSARY!
Images and Accelerators (short-cuts). Short-cuts are added to the right side on a menu. the exact same location is also used for images. An image is a graphical short-cut.
Images are recessive to keyboard short-cuts.
A glyph should be used inside menus to represent images. Specify this inside th option database.
option add *Menu.sampleImage x option add *Menu.glyphfont {apple symbols}
... replaces the image 'sampleImage' with glyph 'x' from font 'apple symbols' inside of every striped menu.
Images are recessive to glyph.
Under »AQUA« two gradients are used for controls. The gradient »aquagradient« creates is layered beneath the normal gradient. The conventional normal gradient is semi transparent under AQUA. Use opaque gradients for custom-made gradients directly added to the gradient cache.
And »left« control the mouse movement inside a stripe object. <Enter> and <Leave> events must be handled with great care! Otherwise a deadlock will ensue in various circumstances (e.g. modal dialogs). To delay the <Leave> event until a new <Enter> event arrives allows to carry the active state over to an reentrant call in another item of the same element – which is how it is used.
This does –not yet– work properly within tkpath.
Can’t be used in response to a configure action to its associated »window«. It is required to integrate this function in the host template instead –can’t be done automatically. Preferred way to notify the text item about changes in its associated »window«
Retrieve the leading window for the »group«, of which »window« is a member.
The secondary constructor to a gstripes window.
Try to start at the same position for the stripes. NOTE : This scrolling isn't necessary for the goolbar. Warning, calling the internal stripes does not expect the template window, but the 'canvas'. Adjustment doesn't make sense after the window is created ... the action has to be performed when the window was mapped onto the screen.
Extended with local caché. These caché is meant for tkpath 0.3.0, otherwise a global caché is used for this modul.
See also : default-destroy, gradient and aquagradient.
Create a tkpath gradient for the given control, or reuse a suitable gradient, if it does exist. Do check the gradients before reuse – might have gone missing.
SEE ALSO REPAIRSTRIPES AND REPAIRCOMMAND.
There is a second »gradient« version for AQUA®. The AQUA® variant uses an elaborated gradient with approximately twelve stops.
With »tkpath« gradient can be pre-defined. Pre-defined gradients are used as they are.
New tkpath 0.3.0 requires a local caché, therefor ported to gcache.
See also »gestaltvector« for caché.
Internal used! Is called to trace selection inside of »menu«. The menu entry »i« is the current selected menu entry and its colors must change to reflect this selection inside of the stripes window »base«. A prior menu entry might have had the selection –very likely– and thus the colors must be restored for this entry, too.
As with the »leave« event in general, menuupdate may be called post-mortem.
Test wheter »gradient« is indeed a gradient. Returns 0 for a simple color.
Works for TkPath 0.2 and 0.3.
Create AQUA stripes inside the canvas. These stripes are semi-transparent when 'tkpath' is present.
Note 10/25/2007 - 11:51 : Stripes are used inside the goolbar, too. Drawing area for stripes ... These functions do not »legally« belong to the Stripes template.
Produces the bindings needed to navigate and communicate position for the »menu« and its associated stripes child window.
Called from within hijackgroup if the first item in args is of class "Frame".
The contour is always created with the first frame as the basis of the outline. Subsequent frames are only evaluated when overlapping with the first frame.
All frames are considered, regardless how and with whom they overlap. The process is as follows: All rectangles are tested against the previous tested rectangles (frames). If they intersect: new rectangles are generated. This is repeated until there are no longer any overlapping rectangles. After that the non-overlapping rectangles are combined into a single path object... The rectangle corners are the coordinates of the path item.
Note 12/17/2007 - 15:40 : ➊ hijackcontour assumes inert frames. This is different to a conventional background frame.
Make an application specific <Configure> binding, for selected contour items, if they are not inert. Try to avoid doing this for the entire group, thou! Of course, general geometry changes are processed.
Interact handler for hijacked buttons and menubuttons. Only selected events are processed by interactive.