Module: environment-framework Synopsis: Environment Framework Author: Andy Armstrong, Chris Page 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 /// Selection define open generic frame-selection (frame :: ) => (selection); define open generic frame-selection-empty? (frame :: ) => (empty? :: ); define open generic frame-selected-text (frame :: ) => (text :: false-or()); define open generic note-frame-selection-updated (frame :: ) => (); define open generic frame-sheet-with-selection (frame :: ) => (sheet :: false-or()); define open generic frame-sheet-selection (frame :: , sheet :: ) => (selection); define open generic frame-sheet-selection-empty? (frame :: , sheet :: ) => (empty? :: ); define open generic frame-sheet-selected-text (frame :: , sheet :: ) => (text :: false-or()); /// define open abstract class () end class ; define method initialize (frame :: , #key) => () next-method(); note-frame-selection-updated(frame) end method initialize; define method note-frame-input-focus-changed (frame :: ) => () next-method(); note-frame-selection-updated(frame) end method note-frame-input-focus-changed; define method note-frame-selection-updated (frame :: ) => () #f end method note-frame-selection-updated; /// Selection commands define open abstract class () end class ; define class () end class ; define class () end class ; /// Collection gadget selections define method execute-command-for-focus (gadget :: , command :: ) => () let frame = sheet-frame(gadget); when (gadget-selection-mode(gadget) = #"multiple") gadget-selection(gadget) := #"all"; note-frame-selection-updated(frame) end end method execute-command-for-focus; define method execute-command-for-focus (gadget :: , command :: ) => () let frame = sheet-frame(gadget); when (gadget-selection-mode(gadget) ~= #"none") gadget-selection(gadget) := #[]; note-frame-selection-updated(frame) end end method execute-command-for-focus; define method command-available-for-focus? (gadget :: , command == ) => (available? :: ) gadget-selection-mode(gadget) == #"multiple" & size(gadget-selection(gadget)) ~= size(gadget-items(gadget)) end method command-available-for-focus?; define method command-available-for-focus? (gadget :: , command == ) => (available? :: ) gadget-selection-mode(gadget) == #"multiple" & ~empty?(gadget-selection(gadget)) end method command-available-for-focus?; /// Text gadget selections define method execute-command-for-focus (gadget :: , command :: ) => () text-selection(gadget) := #t end method execute-command-for-focus; define method execute-command-for-focus (gadget :: , command :: ) => () text-selection(gadget) := #f end method execute-command-for-focus; define method command-available-for-focus? (gadget :: , command == ) => (available? :: ) //--- There must be a more efficient way to do this! selected-text(gadget) ~= gadget-text(gadget) end method command-available-for-focus?; define method command-available-for-focus? (gadget :: , command == ) => (available? :: ) false?(selected-text(gadget)) end method command-available-for-focus?; /// Default implementations define method frame-selection (frame :: ) => (selection) let sheet = frame-sheet-with-selection(frame); sheet & frame-sheet-selection(frame, sheet) end method frame-selection; define method frame-selection-empty? (frame :: ) => (empty? :: ) let sheet = frame-sheet-with-selection(frame); ~sheet | frame-sheet-selection-empty?(frame, sheet) end method frame-selection-empty?; define method frame-selected-text (frame :: ) => (text :: false-or()) let sheet = frame-sheet-with-selection(frame); (sheet & frame-sheet-selected-text(frame, sheet)) | begin let selection = frame-selection(frame); instance?(selection, ) & selection end end method frame-selected-text; //---*** This seems a bit dubious, in that it ignores //---*** non-collection gadgets. Maybe the name should just //---*** be changed to reflect this. define method frame-selected-objects (frame :: ) => (objects :: ); let gadget = frame-primary-collection-gadget(frame); if (gadget) select (gadget-selection-mode(gadget)) #"multiple" => gadget-value(gadget); #"single" => if (empty?(gadget-selection(gadget))) #[] else vector(gadget-value(gadget)) end; otherwise => #[] end else #[] end end method frame-selected-objects; define method frame-sheet-with-selection (frame :: ) => (sheet :: false-or()) #f end method frame-sheet-with-selection; define method frame-primary-collection-gadget (frame :: ) => (gadget :: false-or()) let sheet = frame-sheet-with-selection(frame); instance?(sheet, ) & sheet end method frame-primary-collection-gadget; define method frame-sheet-selection (frame :: , sheet :: ) => (selection) #f end method frame-sheet-selection; define method frame-sheet-selection (frame :: , gadget :: ) => (selection) if (gadget-selection-mode(gadget) == #"multiple") //---*** DUIM should really do this for us, plus it should never //---*** return duplicates but unfortunately it has been known to. let items = gadget-items(gadget); let selection = sort!(remove-duplicates(gadget-selection(gadget))); map-as(, method (index :: ) gadget-item-value(gadget, items[index]) end, selection) else gadget-value(gadget) end end method frame-sheet-selection; define method frame-sheet-selection (frame :: , gadget :: ) => (selection) gadget-value(gadget) end method frame-sheet-selection; define method frame-sheet-selection-empty? (frame :: , sheet :: ) => (empty? :: ) #t end method frame-sheet-selection-empty?; define method frame-sheet-selection-empty? (frame :: , gadget :: ) => (empty? :: ) empty?(gadget-selection(gadget)) end method frame-sheet-selection-empty?; define method frame-sheet-selection-empty? (frame :: , gadget :: ) => (empty? :: ) text-selection(gadget) == #f end method frame-sheet-selection-empty?; define method frame-sheet-selected-text (frame :: , sheet :: ) => (text :: false-or()) #f end method frame-sheet-selected-text; define method frame-sheet-selected-text (frame :: , gadget :: ) => (text :: false-or()) let selection = gadget-selection(gadget); let items = gadget-items(gadget); select (size(selection)) 0 => #f; 1 => let index = selection[0]; gadget-item-label(gadget, items[index]); otherwise => let stream = make(, direction: #"output"); for (index in sort(selection)) let label = gadget-item-label(gadget, items[index]); format(stream, "%s\n", label); end; stream-contents(stream); end end method frame-sheet-selected-text; define method frame-sheet-selected-text (frame :: , gadget :: ) => (text :: false-or()) // ---*** hughg, 1997/12/18: This is a hack because currently some DUIM // return #f for the selected text. If you want to // get some of the text, better get all than none. selected-text(gadget) | gadget-text(gadget) end method frame-sheet-selected-text; /// Selection command table define command-table *selection-command-table* (*global-command-table*) menu-item "Select All" = , documentation: "Selects all items or information."; //--- cpage: 1997.11.09 Remove Deselect All. I've left all the code in place // to minimize the number of changes, and in case we decide to use // it again. If not, remove it at some point. /* menu-item "Deselect All" = , documentation: "Deselects selected items."; */ end command-table *selection-command-table*;