Module: environment-tools Synopsis: Environment tools 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 /// View state // // This is the class of objects that remember the state of a particular // object's view in the browser history. define class () constant slot state-object :: , required-init-keyword: object:; slot state-page :: false-or() = #f; slot state-properties :: false-or() = #f; end class ; /*---*** andrewa: try taking this out again //---*** andrewa: temporary hack until this is working properly define method state-object (object) => (object) object end method state-object; */ /// Object Browser define frame (, , , , ) constant slot object-browser-page = #f, init-keyword: page:; //---*** cpage: 1997.11.10 Experiment with Explorer Bars /* pane object-hierarchy-pane (frame) make(, max-width: 50, frame: frame); /* make(, max-width: 200, selection-mode: #"single", depth: 1, children-generator: method (object) object-browser-children-generator(frame, object) end, label-key: curry(frame-default-object-name, frame), popup-menu-callback: display-environment-popup-menu, value-changed-callback: method (sheet) let frame = sheet-frame(sheet); note-frame-selection-updated(frame); refresh-frame-view(frame); frame-primary-object(sheet-frame(sheet)) := gadget-value(sheet) end); */ /*, activate-callback: method (sheet) let target = gadget-value(sheet); environment-activate-callback(sheet, target) end); */ */ //---*** cpage: 1997.11.10 Removing the primary object displayer in anticipation // of having an "explorer bar" to the left of the property pages, // which would display (among other things) the primary object. /* pane object-browser-primary-object-displayer (frame) make(, view: #"small-icon", scroll-bars: #"none", //--- cpage: 1997.09.14 This is a hack; when there is no object, the list // goes to "infinite" height. I don't know the right way to do // this. I want the "list" to always be the height of one item. max-height: 12, label-key: curry(frame-object-unique-name, frame), activate-callback: execute-displayer-gadget-activate-callback, popup-menu-callback: display-environment-popup-menu); */ pane object-browser-object-bar (frame) make(, child: vertically (spacing: 2) make(); make-frame-primary-object-selector(frame, label: "Object"); end); pane tab-layout (frame) make(, class: frame-primary-object-class(frame), frame: frame, page: object-browser-page(frame), value-changed-callback: method (pane) let state :: false-or() = frame-raw-primary-object(frame); if (state) let page = environment-property-pane-page(pane); state-page(state) := page end end, activate-callback: environment-activate-callback); pane main-layout (frame) vertically (spacing: 2) frame.object-browser-object-bar; make(); //---*** cpage: 1997.11.10 Removing the primary object displayer in anticipation // of having an "explorer bar" to the left of the property pages, // which would display (among other things) the primary object. // frame.object-browser-primary-object-displayer; horizontally (spacing: 2) //---*** cpage: 1997.11.10 Experiment with Explorer Bars /* frame.object-hierarchy-pane; */ frame.tab-layout; end end; layout (frame) frame.main-layout; tool-bar (frame) make-environment-tool-bar(frame); status-bar (frame) make-environment-status-bar(frame); command-table (frame) *object-browser-command-table*; keyword width: = $default-environment-frame-width; keyword height: = $default-environment-frame-height; keyword icon: = $browser-window-small-icon; keyword frame-class-name:, init-value: #"object-browser"; end frame ; define cascading-window-settings browser :: = "Browser"; define method frame-coerce-raw-object (frame :: , object :: ) => (object) object.state-object end method frame-coerce-raw-object; // Frame initialization define method reinitialize-frame (frame :: , #key project :: , page :: false-or()) => () next-method(); //---*** cpage: 1997.11.15 We probably want to remove the project parameter // since object browsers are tied to a single project. frame.%frame-project := project; when (page) environment-property-pane-page(frame.tab-layout) := page; end; frame-ensure-project-database(frame); end method reinitialize-frame; define method handle-event (frame :: , event :: ) => () with-busy-cursor (frame) next-method(); frame-ensure-project-database(frame); end end method handle-event; /// Toolbars etc //---*** cpage: 1997.11.10 Temporary(?) kludge: This is a modified copy of // the code in the framework, so that we can have a custom // tool bar (the Object selector). Eventually, we need to // expand the framework protocol to allow for this. /// Bar options (tool bar, status bar etc) define command-table *object-browser-bar-options-command-table* (*global-command-table*) end command-table *object-browser-bar-options-command-table*; add-command-table-menu-item (*object-browser-bar-options-command-table*, "", , vector(#"tool-bar", #"object-bar", #"status-bar"), items: #[#["Toolbar", #"tool-bar"], #["Object Bar", #"object-bar"], #["Status Bar", #"status-bar"]], label-key: first, value-key: second, callback: method (menu-box) frame-show-bars?(sheet-frame(menu-box), gadget-value(menu-box)) end); define method frame-show-bars? (frame :: , bars :: ) => () let top-sheet = top-level-sheet(frame); let tool-bar = frame-tool-bar(frame); let object-bar = object-browser-object-bar(frame); let status-bar = frame-status-bar(frame); let tool-bar? = member?(#"tool-bar", bars); let object-bar? = member?(#"object-bar", bars); let status-bar? = member?(#"status-bar", bars); let relayout? = #f; local method show-or-hide (sheet, present?) => () // Work extra hard to ensure that everything gets re-layed out, // since bars can have associated "decorations" when (sheet & sheet-withdrawn?(sheet) == present?) sheet-withdrawn?(sheet) := ~present?; for (s = sheet then sheet-parent(s), until: s == top-sheet) sheet-layed-out?(s) := #f end; relayout? := #t end end method show-or-hide; show-or-hide(tool-bar, tool-bar?); show-or-hide(object-bar, object-bar?); show-or-hide(status-bar, status-bar?); when (relayout?) relayout-children(top-sheet); relayout-parent(tool-bar | object-bar | status-bar); sheet-mapped?(tool-bar) := tool-bar?; sheet-mapped?(object-bar) := object-bar?; sheet-mapped?(status-bar) := status-bar?; end end method frame-show-bars?; /// Clipboard support define method clipboard-object-to-browse (frame :: ) => (object) let object = dylan-clipboard-object(frame); select (object by instance?) => let project = frame.frame-project; if (environment-object-home-server?(project, object)) object else //---*** Note that environment-object-id ignores the project, //---*** which is good because this is not its owner project! //---*** Really environment-object-id shouldn't take a server. let id = environment-object-id(project, object); id & find-environment-object(project, id) end; => find-named-object(frame, object); otherwise => #f; end end method clipboard-object-to-browse; define method paste-object? (frame :: , object) => (paste? :: ) ignore(object); clipboard-object-to-browse(frame) ~= #f end method paste-object?; define method paste-object (frame :: , object) => () ignore(object); let object = clipboard-object-to-browse(frame); if (object) frame-browse-object(frame, object) else let object-name = with-clipboard (clipboard = top-level-sheet(frame)) if (clipboard-data-available?(, clipboard)) get-clipboard-data-as(, clipboard) end end; let message = if (object-name & size(object-name) < $maximum-object-name-length) format-to-string ("Cannot paste '%s' as it was not found in this project", object-name) else "Cannot browse the current clipboard contents" end; environment-error-message(message, owner: frame) end end method paste-object; /// Tool-bar buttons define method make-browse-tool-bar-buttons (frame :: ) => (buttons :: ) let project = frame.frame-project; vector(make(