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 /// Primary object API // #f always means "no object" define open abstract class () sealed slot frame-raw-primary-object :: = #f, init-keyword: object:; sealed slot frame-name-selector :: false-or() = #f; sealed slot frame-last-name :: false-or() = #f; sealed slot frame-last-callback :: false-or() = #f; end class ; //---*** Restricting these to loses, // which seems too bad define open generic frame-primary-object (frame :: ) => (object :: ); define open generic frame-default-primary-object (frame :: ) => (object :: ); define open generic frame-coerce-raw-object (frame :: , object :: ) => (object :: ); define open generic frame-coerce-primary-object (frame :: , object :: ) => (object :: ); define open generic frame-coerce-object (frame :: , object :: ) => (object :: ); define open generic frame-primary-object-name (frame :: , object :: ) => (name :: ); define open generic note-primary-object-changed (frame :: , old-object :: ) => (); define open generic note-raw-primary-object-replaced (frame :: , old-object :: ) => (); define open generic frame-primary-object-class (frame :: ) => (class :: ); define open generic frame-select-primary-object (frame :: , #key title, label, prompt) => (); /// Initialization define method handle-event (frame :: , event :: ) => () next-method(); // Get the raw primary object (set in initialize), and set the // primary object, which will call notification functions, etc. let object = frame.frame-raw-primary-object; case object => frame-raw-primary-object(frame) := #f; frame-primary-object(frame) := object; ~frame-raw-primary-object(frame) => let default-object = frame-default-primary-object(frame); if (default-object) frame-primary-object(frame) := default-object end; //--- cpage: 1998.03.10 I don't think the otherwise case can occur. // Consider deleting this. otherwise => /* Do nothing */; end case; end method handle-event; define method reinitialize-frame (frame :: , #key object) => () next-method(); if (object) //---*** cpage: 1998.09.01 This line plays havoc with functions that want to // know whether the new object is the same as the old. Before // frame-raw-primary-object was created, this line used to // reset %object. I suspect it did so to ensure that the frame // frame was refreshed. I'm leaving this here for a while, till // we have tested this change. // frame.frame-raw-primary-object := #f; frame-primary-object(frame) := object end; end method reinitialize-frame; define method frame-coerce-raw-object (frame :: , object :: ) => (object :: ) object end method frame-coerce-raw-object; define method frame-primary-object (frame :: ) => (object :: ) frame-coerce-raw-object(frame, frame-raw-primary-object(frame)) end method frame-primary-object; define method frame-default-primary-object (frame :: ) => (object :: ) #f end method frame-default-primary-object; define method frame-coerce-object (frame :: , object :: ) => (object :: ) instance?(object, frame-primary-object-class(frame)) & object end method frame-coerce-object; define method frame-coerce-object (frame :: , name :: ) => (object :: false-or()) find-named-object(frame, name) end method frame-coerce-object; define method frame-coerce-primary-object (frame :: , object :: ) => (object :: ) frame-coerce-object(frame, object) end method frame-coerce-primary-object; define method note-primary-object-changed (frame :: , old-object :: ) => () #f end method note-primary-object-changed; define method note-raw-primary-object-replaced (frame :: , old-object :: ) => () #f end method note-raw-primary-object-replaced; define method frame-primary-object-setter (object :: , frame :: ) => (object :: ) let old-raw-object = frame-raw-primary-object(frame); let old-object = frame-primary-object(frame); let raw-object = object & frame-coerce-primary-object(frame, object); when (object & ~raw-object) let message = format-to-string(if (instance?(object, )) "Cannot find an object named '%s'." else "Cannot find object %=." end, object); notify-user(message, owner: frame); end; when (raw-object & raw-object ~== old-raw-object) frame.frame-raw-primary-object := raw-object; raw-object & frame-add-to-history(frame, raw-object); old-raw-object & note-raw-primary-object-replaced(frame, old-raw-object); note-primary-object-changed(frame, old-object); end; object end method frame-primary-object-setter; define method frame-select-object (frame :: , object :: ) => () next-method(); frame-primary-object(frame) := object end method frame-select-object; define method note-frame-last-object-closed (frame :: ) => () next-method(); frame.frame-raw-primary-object := #f; end method note-frame-last-object-closed; define method frame-primary-object-class (frame :: ) => (class :: ) end method frame-primary-object-class; define method make-frame-primary-object-selector (frame :: , #key label = "Object:") => (sheet :: ) local method find-named-object-in-history (name :: ) => (object) let name = as-lowercase(name); block (return) for (raw-object in frame-history(frame)) let object = frame-coerce-raw-object(frame, raw-object); let object-name = as-lowercase(frame-primary-object-name(frame, object)); if (name = object-name) return(raw-object) end end end end method find-named-object-in-history; local method update-primary-object (gadget :: , callback :: ) => () let frame = sheet-frame(gadget); with-busy-cursor (frame) let name = gadget-value(gadget); //--- This is a grotesque hack to avoid updating twice, //--- first from the value changed callback and then //--- again from the activate callback. unless (name == frame.frame-last-name & callback == #"activate" & frame.frame-last-callback == #"value-changed") let object = find-named-object-in-history(name) | name; frame-primary-object(frame) := object end; frame.frame-last-name := name; frame.frame-last-callback := callback; end end method update-primary-object; let object = frame-primary-object(frame); horizontally (spacing: 2, y-alignment: #"center") make(