Module: duim-frames-internals Synopsis: DUIM frames Author: Jason Trenouth, Scott McKay, Andy Armstrong Copyright: Original Code is Copyright (c) 1995-2004 Functional Objects, Inc. All rights reserved. License: Functional Objects Library Public License Version 1.0 Dual-license: GNU Lesser General Public License Warranty: Distributed WITHOUT WARRANTY OF ANY KIND /// Help systems define open abstract class () sealed constant slot help-system-name :: , required-init-keyword: name:; end class ; define variable *default-help-system* :: false-or() = #f; // NB: This is for testing the installation of a Help System (viewer) and // not any particular form of Help content define open generic help-system-installed? (system :: ) => (installed? :: ); define method help-system-installed? (system :: ) => (installed? :: ) #t end method help-system-installed?; define open generic frame-manager-help-system (framem :: ) => (system :: false-or()); define open generic frame-manager-help-system-setter (system :: false-or(), framem :: ) => (system :: false-or()); define method frame-manager-help-system (framem :: ) => (system :: false-or()) *default-help-system* end method frame-manager-help-system; define method frame-manager-help-system-setter (system :: false-or(), framem :: ) => (system :: false-or()) *default-help-system* := system end method frame-manager-help-system-setter; /// Help systems errors define class () end class ; define class () keyword format-string: = "%s is not installed"; end class ; define method make (class == , #key system) => (condition :: ) next-method(class, format-arguments: vector(help-system-name(system))) end method make; define class () keyword format-string: = "There is no help system defined."; end class ; /// Help define constant = false-or(type-union(, one-of(#"by-gesture", #"by-focus"))); define constant = type-union(, ); define protocol <> () getter help-source (command :: ) => (source :: false-or()); getter help-secondary-window (command :: ) => (window-name :: false-or()); getter help-pane (command :: ) => (pane :: ); getter help-context (command :: ) => (context :: false-or()); getter help-topic-id (command :: ) => (topic-id); getter help-popup? (command :: ) => (pop-up? :: ); getter help-keyword (command :: ) => (keyword :: false-or()); getter help-macro (command :: ) => (_macro :: ); getter help-window-region (command :: ) => (region :: ); // Initialization function initialize-help-pane (command :: , frame :: ) => (); function initialize-help (command :: , frame :: ) => (); // Glue to commands function display-help (framem :: , frame :: , command :: ) => (); // Glue to frames function frame-help-source-locator (frame :: , source :: ) => (locator); function frame-help-source (frame :: , command :: ) => (source :: false-or()); function frame-help-context (frame :: , command :: ) => (context :: false-or()); function frame-help-topic-id (frame :: , command :: ) => (topic-id); function frame-help-keyword (frame :: , command :: ) => (keyword :: false-or()); end protocol <>; /// Help Sources // Reify entity for refering to a help source file and its mapping // from symbolic help contexts to whatever identifiers are required // by the help system: eg integers, strings, urls, or whatever. define constant $help-sources :: = make(); define sealed class () sealed constant slot help-source-name :: , required-init-keyword: name:; sealed slot help-source-locator :: false-or() = #f, init-keyword: locator:; sealed constant slot help-source-context-map :: false-or() = #f, init-keyword: contexts:; end class ; define sealed method initialize (source :: , #key name :: ) next-method(); $help-sources[name] := source end method initialize; define macro help-source-definer { define help-source ?name:name ?locator:expression ?entries:* end } => { make(, name: ?#"name", locator: ?locator, contexts: initialize-table (make(
)) ?entries end) } end macro help-source-definer; define macro initialize-table { initialize-table (?table-name:expression) ?entries:* end } => { let the-table = ?table-name; ?entries; the-table } entries: { } => { } { ?key:expression => ?value:expression; ... } => { the-table[?key] := ?value; ... } end macro initialize-table; define method as (class == , source :: ) => (source :: ) source end method as; define method as (class == , name :: ) => (source :: ) $help-sources[name] end method as; /// Help Commands // and its subclasses model the standard kinds of help that // users are normally able to invoke. Most classes have a 'help-source' // associated with them. Some have additional state, such as a 'help-context'. define open abstract primary class () end class ; // Help on a specific subject define open abstract primary class () end class ; // Help about using the help system itself define sealed class () end class ; // "About" box help define sealed class () end class ; // Help on something with an explicit source define open abstract primary class () sealed slot help-source :: false-or() = #f, init-keyword: source:; sealed slot help-secondary-window :: false-or() = #f, init-keyword: secondary-window:; end class ; // Help topics page (supersedes index and contents in Win95) define sealed class () end class ; // Help index page define sealed class () end class ; // Help contents page define sealed class () end class ; // Help on some UI element define open abstract primary class () sealed slot help-pane :: false-or() = #f, init-keyword: pane:; end class ; define method find-pane-by-gesture (frame :: ) => (pane :: false-or()) // Go into special mode so user can select pane they are interested in //---*** Do this error("Not implemented yet!") end method find-pane-by-gesture; define method find-pane-by-focus (frame :: ) => (pane :: false-or()) frame-mapped?(frame) & frame-input-focus(frame) end method find-pane-by-focus; define method default-from-sheet (sheet :: false-or(), getter :: ) => (default) block (return) for (sh = sheet then sheet-parent(sh), until: ~sh) let value = getter(sh); when (value) return(value) end end; #f end end method default-from-sheet; // Help on predefined topic // Sometimes called "What is this?" define sealed class () sealed slot help-context :: false-or() = #f, init-keyword: context:; sealed slot help-topic-id = #f, init-keyword: topic-id:; sealed slot help-popup? :: = #f, init-keyword: popup?:; end class ; // Help on arbitrary string define sealed class () sealed slot help-keyword :: false-or() = #f, init-keyword: keyword:; end class ; // Help system macro define sealed class () sealed slot help-macro :: , required-init-keyword: macro:; end class ; // Help window can be repositioned define sealed class () sealed slot help-window-region :: , required-init-keyword: region:; end class ; // Help system is no longer needed //---*** Needs to register a callback with DUIM exiting mechanism define sealed class () end class ; // Initializes command pane define method initialize-help-pane (command :: , frame :: ) => () #f end method initialize-help-pane; define method initialize-help-pane (command :: , frame :: ) => () select (help-pane(command)) #"by-gesture" => help-pane(command) := find-pane-by-gesture(frame); #"by-focus" => help-pane(command) := find-pane-by-focus(frame); otherwise => #f; end end method initialize-help-pane; // Initializes command from frame define method initialize-help (command :: , frame :: ) => () #f end method initialize-help; define method initialize-help (command :: , frame :: ) => () next-method(); help-source(command) := as(, help-source(command) | frame-help-source(frame, command)); help-source-locator(help-source(command)) := help-source-locator(help-source(command)) | frame-help-source-locator(frame, help-source(command)); end method initialize-help; define method initialize-help (command :: , frame :: ) => () next-method(); help-context(command) := help-context(command) | frame-help-context(frame, command); help-topic-id(command) := help-topic-id(command) | frame-help-topic-id(frame, command); end method initialize-help; define method initialize-help (command :: , frame :: ) => () next-method(); help-keyword(command) := help-keyword(command) | frame-help-keyword(frame, command); end method initialize-help; /// Glue to Commands define method do-execute-command (frame :: , command :: ) => () initialize-help-pane(command, frame); initialize-help(command, frame); display-help(frame-manager(frame), frame, command) end method do-execute-command; define method do-execute-command (frame :: , command :: ) => () // The idea here is that hackers write their own method for this... #f end method do-execute-command; /// Glue to Frames define method frame-help-source-locator (frame :: , source :: ) => (locator :: singleton(#f)) #f end method frame-help-source-locator; define method frame-help-source (frame :: , command :: ) => (source :: singleton(#f)) #f end method frame-help-source; define method frame-help-source (frame :: , command :: ) => (source :: false-or()) default-from-sheet(help-pane(command), sheet-help-source) end method frame-help-source; define method frame-help-context (frame :: , command :: ) => (context :: false-or()) default-from-sheet(help-pane(command), sheet-help-context) end method frame-help-context; define method frame-help-keyword (frame :: , command :: ) => (keyword :: false-or()) default-from-sheet(help-pane(command), selected-text) end method frame-help-keyword; define method frame-help-topic-id (frame :: , command :: ) => (object) help-source-context-map(help-source(command))[help-context(command)] end method frame-help-topic-id;