All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.smartclient.debug.public.sc.client.widgets.Window.js Maven / Gradle / Ivy

The newest version!
/*
 * Isomorphic SmartClient
 * Version SC_SNAPSHOT-2011-08-08 (2011-08-08)
 * Copyright(c) 1998 and beyond Isomorphic Software, Inc. All rights reserved.
 * "SmartClient" is a trademark of Isomorphic Software, Inc.
 *
 * [email protected]
 *
 * http://smartclient.com/license
 */

 


//> @class Window
//
// A general purpose Window class for implementing dialogs, portlets, alerts, prompts, wizards
// and desktop-like windowing interfaces.
// 

// Windows can contain arbitrary SmartClient components, configured via the +link{window.items} // property. Windows may be +link{window.isModal,modal} or non-modal. //

// Windows provide a series of highly configurable and skinnable +link{AutoChild,autoChildren} // including a header, various header controls, footer, and corner resizer. //

// The more specialized +link{Dialog} subclass of Window has additional functionality targetted // at simple prompts and confirmations, such as buttons with default actions, and single-method // +link{classMethod:isc.warn(),shortcuts} for common application dialogs. // // @treeLocation Client Reference/Layout // @visibility external //< isc.ClassFactory.defineClass("Window", "Layout"); //> @groupDef body // Things related to the body subobject of Window // @visibility internal //< //> @groupDef header // Things related to the header subobject of Window // @visibility internal //< //> @groupDef headerLabel // Things related to the headerLabel subobject of Window // @visibility internal //< //> @groupDef footer // Things related to the footer subobject of Window // @visibility internal //< //> @groupDef windowItems // Things related to the items contained in the Window body // @title Window Items // @visibility internal //< // add standard instance properties isc.Window.addProperties({ // Skinning // --------------------------------------------------------------------------------------- //> @attr window.styleName (string : "windowBackground" : IRW) // Default style for the Window background // @group appearance, header //< styleName:"windowBackground", //> @attr window.skinImgDir (URL : "images/Window/" : IRWA) // Where do 'skin' images (those provided with the class) live? // This is local to the Page.skinDir // @group appearance, images //< skinImgDir:"images/Window/", //> @attr window.backgroundColor (string : "#DDDDDD" : IRW) // background color, picked up in Header, Footer, etc. // @group appearance, header //< backgroundColor:"#DDDDDD", layoutMargin:2, membersMargin:2, // set orientation to vertical by default orientation: "vertical", // Dragging // --------------------------------------------------------------------------------------- dragStartDistance:1, //> @attr window.canDragReposition (boolean : true : IRW) // If true, this Window may be moved around by the user by dragging on the Window header. // Note that if the header is not showing, the Window can't be drag-repositioned regardless // of this setting. // @see window.showHeader // @group dragging // @visibility external //< canDragReposition:true, //> @attr window.keepInParentRect (boolean or rect: null : IRWA) // If +link{window.canDragReposition} or +link{window.canDragResize} is true, should the // windows size and position be constrained such that it remains within the viewport of // its parent element (or for top level windows, within the viewport of the browser window)? //
// Can also be set to an array denoting an arbitrary rect [Left,Top,Width,Height] beyond // which the window cannot be moved. //

// Note: keepInParentRect affects only user drag interactions, not programmatic moves. // // @see window.canDragReposition // @group dragdrop // @visibility external //< dragAppearance : isc.EventHandler.OUTLINE, // Drag Resizing // --------------------------------------------------------------------------------------- //> @attr window.canDragResize (boolean : false : IRW) // Can the window be drag-resized? If true the window may be drag resized from its edges, // and if showing, via the resizer icon in the footer. // @see window.showResizer // @group dragging, resizing // @visibility external //< canDragResize:false, //> @attr window.resizeFrom (array : ["R","B","BR"] : IRWA) // which parts of the window can be clicked and // dragged to resize it? // @group resizing //< resizeFrom:["R","B","BR"], // quick fix for odd drawing behaviors when window is too small minWidth:100, minHeight:100, // Internal // --------------------------------------------------------------------------------------- useBackMask: isc.Browser.isIE && isc.Browser.minorVersion >= 5.5, // Modality // --------------------------------------------------------------------------------------- //> @attr window.isModal (boolean : false : [IRW]) // If true, when shown this Window will intercept and block events to all other existing // components on the page. //

// Use +link{showModalMask} to darken all other elements on the screen when a modal dialog // is showing. //

// Chained modal windows - that is, modal windows that launch other modal windows - are // allowed. You can accomplish this by simply creating a second modal Window while a modal // Window is showing. //

// Note only top-level Windows (Windows without parents) can be modal. // // @group modal // @visibility external // @example modality //< isModal : false, //> @attr window.modalMask (AutoChild : null : R) // A ScreenSpan instance used to darken the rest of a page when a modal window is // active. To use, set +link{window.showModalMask} to true, add a CSS style // "modalMask" to the active skin (generally with background-color set), // and adjust +link{window.modalMaskOpacity}. // @group modal, appearance // @visibility external //< //> @attr window.showModalMask (boolean : null : IR) // If true, displays a translucent mask over the rest of the page when a modal window // is displayed. // @group modal, appearance // @see window.modalMask // @visibility external //< //> @attr window.modalMaskOpacity (number : 50 : IR) // Controls the opacity of the modal mask displayed behind modal windows. // @group modal, appearance // @see window.modalMask // @visibility external //< modalMaskOpacity: 50, //> @attr window.modalMaskStyle (string : "modalMask" : IR) // Specifies the CSS style for the modal mask. // @group modal, appearance // @see window.modalMask // @visibility external //< modalMaskStyle: "modalMask", modalMaskConstructor: "ScreenSpan", //> @attr window.autoCenter (boolean : autoCenter : [IRW]) // If true, this Window widget will automatically be centered on the page when shown. // If false, it will show up in the last position it was placed (either programmatically, // or by user interaction). // @group appearance, location // @visibility external //< //autoCenter : false, // Dismissal // --------------------------------------------------------------------------------------- //> @attr window.dismissOnOutsideClick (boolean : false : [IRW]) // If true, a click outside the bounds of the Window will have the same effect as // pressing its cancel button.
// Note: Applies only to modal windows. // @visibility external // @group modal // @see isModal //< dismissOnOutsideClick:false, //> @attr window.dismissOnEscape (boolean : null : [IRW]) // Should this window be dismissed (same effect as pressing the "Cancel" button) when the // user presses the "Escape" key? Behavior will only occur while the window or one of its // descendants has focus, and does not cancel the Escape keypress. //

// If unset default behavior depends on whether a close / cancel button is visible for // this item. // @visibility external // @see window.shouldDismissOnEscape() //< //dismissOnEscape:null, // Body // ---------------------------------------------------------------------------------------- //> @attr window.body (AutoChild : null : R) // Body of the Window, where +link{items,contained components} or +link{src,loaded content} // is shown. // @visibility external //< //> @attr window.showBody (boolean : true : IRWA) // If true, draw the body contents when this Window is drawn. // @visibility external // @group appearance, body //< showBody:true, //> @attr window.bodyStyle (string : "windowBody" : [IRW]) // Style of the Window body. // @visibility external // @group appearance, body //< bodyStyle:"windowBody", //> @attr window.bodyColor (string : "#FFFFFF" : [IRW]) // Color of the Window body. Overrides the background color specified in the style. // @visibility external // @group appearance, body // @see flash() //< bodyColor:"#FFFFFF", //> @attr window.hiliteBodyColor (string : "#EEEEEE" : [IRW]) // Highlight color for the Window body (shown when the body is flashed). // @visibility external // @group appearance, body // @see flash() //< hiliteBodyColor:"#EEEEEE", //> @attr window.items (Array of Canvas, Canvas or String : null : [IR]) // The contents of the Window body. Can be specified three different ways: //

  • an Array of Canvases that will become the children of the Window's body when it // is initialized; the canvases in this array should be created, but not drawn (autodraw: // false). //
  • a single canvas that will become a child of the Window body. //
  • a string that will be set as the body's contents.
// @see body // @visibility external // @group appearance, body //< //> @attr window.src (string : null : [IRW]) // A URL to load as content for the Window's body. If specified, this // attribute will take precedence over the items attribute. //

// Note that setting window.src is essentially a shortcut for setting +link{window.items} // to a single HTMLflow with a specified +link{htmlFlow.contentsURL,contentsURL}. // // @see window.contentsType // @group appearance, body // @visibility external //< //> @attr window.contentsType (string : "page" : IR) // If this window has +link{window.src} specified, this property can be used to indicate // whether the source is a standalone HTML page or an HTML fragment. //

// This is similar to the +link{htmlFlow.contentsType} property - be sure to read the // HTMLFlow documentation to understand circumstances where contentsType:"page" is // unsafe and not recommended. // // @see window.src // @visibility external // @group appearance, body //< contentsType:"page", //> @attr window.bodyConstructor (string : null : IRWA) // The name of the widget class (as a string) to use for the body. If unset the appropriate // constructor type will be determined as follows:
// - if +link{window.items} is defined as an array of widgets, and +link{window.contentLayout} // is not set to "none", bodyConstructor defaults to a +link{class:VLayout}
// - if +link{window.src} is set, bodyConstructor defaults to an +link{class:HTMLFlow}
// - otherwise bodyConstructor will default to a simple +link{class:Canvas}
// Note that if this property is overridden for some window, the specified constructor // should be a subclass of one of these defaults to ensure the window renders out as // expected. // // @group appearance, body // @visibility external //< //> @attr window.bodyDefaults (object : ... : IRWA) // Default properties for the body of the Window
// You can change the class-level bodyDefaults for all Windows by changing this item // or set instance.body to be another object of properties to override for your instance only // @group appearance, body // @visibility external //< bodyDefaults:{ layoutMargin:0 }, // Layout // ---------------------------------------------------------------------------------------------- //> @attr window.contentLayout (string : "vertical" : [IRWA]) // The layout policy that should be used for widgets within the Window body. //

// Valid values are "vertical", "horizontal", "none". If the body is a Layout, this // controls how the items are stacked in the body by setting +link{layout.vertical}. // See +link{bodyConstructor} for details. // // @visibility external // @group appearance //< contentLayout:"vertical", //> @attr window.autoSize (boolean : false : [IRW]) // If true, the window is resized automatically to accommodate the contents // of the body, if they would otherwise require scrolling. // @visibility external // @group appearance // @example windowAutosize //< autoSize:false, // Header and Header Components // ---------------------------------------------------------------------------------------------- //> @attr window.header (AutoChild : null : R) // Header for the Window, based on an HLayout. The header contains the title and some standard // controls for the window, which may be configured via +link{window.headerControls}. // @visibility external //< //> @attr window.showHeader (boolean : true : IRWA) // If true, show a +link{window.header} for this Window. //

// Note that in certain Smartclient skins +link{window.showHeaderBackground} may be set to // false and the header's appearance implemented as part of the // window's +link{canvas.showEdges,edge media}. In this case suppressing the header can be achieved // by overriding the edge media as well as setting this property to false. For example, to // create a headerless window with a similar appearance to a +link{Menu} in the // TreeFrog skin, the following attributes could be used: //

    //      showHeader:false,
    //      edgeImage:"[SKIN]/Menu/m.png",
    //      edgeSize:10, edgeTop:17, edgeBottom:17,
    //      edgeCenterBackgroundColor:"#F7F7F7"
    // 
// // @visibility external // @group appearance, header //< showHeader:true, headerConstructor:"HLayout", //> @attr window.headerBackground (AutoChild : null : R) // Img background component for the header, for gradient or image-based display // @visibility external //< //>@attr window.showHeaderBackground (boolean : varies : IRA) // Should the window header show a background image? Default value is true for all browsers // except for Internet Explorer.
// If set to true the image source is derived from +link{window.headerSrc} and // +link{window.hiliteHeaderSrc}, otherwise the background will be styled according to // +link{window.headerStyle} / +link{window.hiliteHeaderStyle}. // @group appearance, header // @visibility external //< // By default, we assume CSS will be used in recent IE, and media otherwise, since the // typical presentation is a gradient. showHeaderBackground : !(isc.Browser.isIE && !isc.Browser.isStrict && isc.Browser.minorVersion >= 5.5), headerBackgroundConstructor: "Img", headerBackgroundDefaults : { width:"100%", height:"100%", // background is a non-member child of the header, which is a Layout addAsChild:true, // applicable to StretchImgs only vertical:false, capSize:10 }, //> @attr window.headerStyle (CSSStyleName : "WindowHeader" : [IRWA]) // Style for the Window header. // @visibility external // @group appearance, header //< headerStyle:"windowHeader", //> @attr window.headerSrc (SCImgURL : "[SKIN]Window/headerGradient.gif" | null : [IRWA]) // If +link{window.showHeaderBackground} is true, this property provides // the URL of the background image for the header. // @group appearance, header // @visibility external //< headerSrc:(!(isc.Browser.isIE && !isc.Browser.isStrict && isc.Browser.minorVersion >= 5.5) ? "[SKIN]Window/headerGradient.gif" : null), headerDefaults:{ // Note - other defaults applied in Window.makeHeader() height:18, layoutMargin:1, membersMargin:2, overflow:isc.Canvas.HIDDEN }, //> @attr window.headerControls (Array of String : (see below) : IR) // Array of members to show in the Window header. //

// The default value of headerControls is an Array of Strings listing the // standard header controls in their default order: //

    //    headerControls : ["headerIcon", "headerLabel", 
    //                      "minimizeButton", "maximizeButton", "closeButton"]
    // 
// You can override headerControls to change the order of standard controls in // the header. You can also omit standard controls this way, although it more efficient to // use the related "show" property if available (eg +link{showMinimizeButton}). //

// By embedding a Canvas directly in this list you can add arbitrary additional controls to // the header, for example, an additional button (eg return to dock) or a DynamicForm with // various kinds of input controls. //

// Note that having added controls to headerControls, you can still call APIs directly on // those controls to change their appearance, and you can also show() and hide() them if // they should not be shown in some circumstances. //

// Tip: custom controls need to set layoutAlign:"center" to appear vertically centered. // // @visibility external // @example windowHeaderControls //< headerControls : ["headerIcon", "headerLabel", "minimizeButton", "maximizeButton", "closeButton"], // Flashing // --------------------------------------------------------------------------------------- //> @attr window.hiliteHeaderStyle (CSSStyleName : "WindowHeader" : [IRWA]) // Highlight style for the Window header. Displayed when a window // is +link{window.flash(), flashed} // @group appearance, header // @visibility external //< hiliteHeaderStyle:"windowHeaderHilite", //> @attr window.hiliteHeaderSrc (SCImgURL : "[SKIN]Window/headerGradient_hilite.gif" | null : [IRWA]) // If +link{Window.showHeaderBackground} is true, this governs the URL of the image to // use in the header's highlighted state when the window is +link{window.flash(), flashed} // @group appearance, header // @visibility external //< hiliteHeaderSrc:(!(isc.Browser.isIE && isc.Browser.minorVersion >= 5.5) ? "[SKIN]Window/headerGradient_hilite.gif" : null), // HeaderLabel settings // -------------------------------------------------------------------------------------------- //> @attr window.headerLabel (AutoChild : null : R) // Label that shows Window title in header. // @visibility external //< //> @attr window.showTitle (boolean : true : [IRW]) // Show a title (typically just text) on the header for this window. // @visibility external // @group appearance, headerLabel //< showTitle:true, //> @attr window.title (HTMLString : "Untitled Window" : [IRW]) // title for this Window, shown in the header (if drawn) // @visibility external // @group appearance, headerLabel, i18nMessages //< title:"Untitled Window", //> @attr window.headerLabelConstructor (Class : Label : IRWA) // The headerLabel for a Window, if shown, will be an instance of this class. // @group appearance, headerLabel //< headerLabelConstructor:"Label", //> @attr window.headerLabelDefaults (Object : see below : IRWA) // // This is an object literal property block specifying various properties of the header // label that displays the +link{Window.title}. Overrideable defaults are as follows: //

    //
  • styleName- defaults to "windowHeaderText" and specifies the css style // that is used to render the +link{Window.title} text. //
// You can override the the above properties by calling +link{Class.changeDefaults()}. // // @group appearance, headerLabel // @visibility external //< // // Default properties for the headerLabel of the Window you can change the class-level // headerLabelDefaults for all Windows by changing this item or set instance.headerLabel to be // another object of properties to override for your instance only headerLabelDefaults:{ wrap:false, align:isc.Canvas.LEFT, styleName:"windowHeaderText", width:10, inherentWidth:true }, // Header icon // -------------------------------------------------------------------------------------------- //> @attr window.headerIcon (AutoChild : null : R) // Header icon shown at left end of header by default. // @visibility external //< //> @attr window.showHeaderIcon (boolean : true : [IRW]) // If true, we show an icon on the left in the header. // @visibility external // @group appearance, header //< showHeaderIcon:true, //> @attr window.headerIconConstructor (Class : Img : IRWA) // The headerIcon for a Window, if shown, // will be an instance of this class. // @group appearance, header //< headerIconConstructor:"Img", //> @attr window.headerIconDefaults (object : ... : IRWA) // // This is an object literal property block specifying the various properties of the // headerIcon - the icon that appears at the top left of the window and is by default the // Isomorphic logo. Overrideable defaults are as follows: //
    //
  • width - default to 16 and specifies the width of the headerIcon. //
  • height - default to 14 and specifies the height of the headerIcon. //
  • src - defaults to "[SKIN]/Window/minimize.gif" and specifies the image // for the headerIcon. //
// You can override the the above properties by calling +link{Class.changeDefaults()}. // // @group appearance, header // @visibility external //< headerIconDefaults:{ width:16, height:16, layoutAlign:"center", src:"[SKIN]/Window/headerIcon.gif" }, // Header buttons // -------------------------------------------------------------------------------------------- //> @attr window.canFocusInHeaderButtons (boolean : false : [IRWA]) // If true, the user can give the header buttons keyboard focus (by clicking on // them and including them in the tabOrder) // @visibility external // @group focus, header //< // Note: this property is applied to the header buttons when they are initialized. canFocusInHeaderButtons:false, // Close button // -------------------------------------------------------------------------------------------- //> @attr window.closeButton (AutoChild : null : R) // Button show in the header that will close this Window by calling +link{closeClick()}. // @visibility external //< //> @attr window.showCloseButton (boolean : true : [IRW]) // If true, show a close button in the header, which will dismiss this window by // calling +link{closeClick()}. // @group appearance, header // @visibility external //< showCloseButton:true, closeButtonConstructor:"ImgButton", closeButtonDefaults:{ width:16, height:14, layoutAlign:"center", src:"[SKIN]/Window/close.gif", click: function () {return this.creator._closeButtonClick()} }, // MinimizeButton (same button as for restoring) // -------------------------------------------------------------------------------------------- //> @attr window.minimizeButton (AutoChild : null : R) // ImgButton shown in the header that will minimize this Window by calling +link{minimize()}. // @visibility external //< //> @attr window.showMinimizeButton (boolean : true : [IRW]) // If true, show a minimize button in the header--clicking it minimizes the Window. // @visibility external // @group appearance, header //< showMinimizeButton:true, minimizeButtonConstructor:"ImgButton", minimizeButtonDefaults:{ width:16, height:14, layoutAlign:"center", src:"[SKIN]/Window/minimize.gif", click:function () { // If onMinimizeClick exists, allow it to cancel default behavior if (!this.creator.onMinimizeClick || (this.creator.onMinimizeClick() != false)) { this.creator.minimize(); } return false } }, //> @attr window.minimized (boolean : false : [IRW]) // Is this window minimized. If true at init time, the window will be drawn minimized. // To set this property at runtime use +link{Window.minimize()} or +link{Window.restore()}. // @visibility external // @group appearance, header //< minimized:false, //> @attr window.defaultMinimizeHeight (number : 16 : [IRWA]) // If +link{window.minimizeHeight} is unset, by the window will shrink to the height of the // header when minimized. //
// If there is no header, the defaultMinimizeHeight will be used instead. // @visibility external // @group appearance, header //< defaultMinimizeHeight:16, //> @attr window.minimizeHeight (number : null : [IRWA]) // Height for the window when minimized. // If unset the window will shrink to the height of the header, if present, otherwise // +link{window.defaultMinimizeHeight,this.defaultMinimizeHeight} // @visibility external // @group appearance, minimize //< //>Animation //> @attr window.animateMinimize (boolean: null : [IRWA]) // Should this window minimize, maximize, and restore as an animation, or as a // simple 1-step transition? // @visibility animation // @group appearance, header, animation // @example windowMinimize //< //animateMinimize:false, //> @attr window.minimizeTime (number : null : [IRWA]) // If this window is minimizeable, and animateMinimize is true, what should the duration of // the minimize / maximize be (in ms)? If unset defaults to canvas.animationTime. // @visibility animation // @group appearance, header, animation // @example windowMinimize //< //minimizeTime : null, //> @attr window.minimizeAcceleration (AnimationAcceleration : null : IRWA) // Default acceleration function for performing an animated minimize / maximize. If unset, // this.animateAcceleration will be used by default instead // @visibility animation // @group appearance, header, animation //< // @attr window.restoreButton (AutoChild : null : R) // ImgButton that restores the Window via +link{restore()}. // @visibility external //< // Note: we currently actually apply these to the minimizeButton to change it on the fly, // we should probably just create both and hide/show restoreButtonDefaults:{ width:16, height:14, src:"[SKIN]/Window/restore.gif", layoutAlign:"center", click:function () { if (!this.creator.onRestoreClick || (this.creator.onRestoreClick() != false)) { this.creator.restore(); } return false } }, // MaximizeButton // -------------------------------------------------------------------------------------------- //> @attr window.maximized (boolean : false : [IRW]) // Is this window maximized. If true at init time, the window will be drawn maximized. // To set this property at runtime use +link{window.maximize()} or +link{window.restore()}. // @visibility external // @group appearance, header //< minimized:false, //> @attr window.maximizeButton (AutoChild : null : R) // Button that will make this Window fill the browser via +link{maximize()}. // @visibility external //< //> @attr window.showMaximizeButton (boolean : false : [IRW]) // If true, show a maximize button in the header - clicking it maximizes the Window // @visibility external // @group appearance, header //< showMaximizeButton:false, maximizeButtonConstructor:"ImgButton", maximizeButtonDefaults:{ width:16, height:14, src:"[SKIN]/Window/maximize.gif", layoutAlign:"center", click:function () { if (!this.creator.onMaximizeClick || (this.creator.onMaximizeClick() != false)) { this.creator.maximize(); } return false } }, // Footer and Footer Components // ------------------------------------------------------------------------------------------ //> @attr window.footer (AutoChild : null : R) // Optional footer for the window, providing space for controls such as the resizer and // status bar. // @visibility external //< //> @attr window.showFooter (boolean : true : [IRW]) // If true, show a footer for this Window, including resizer, statusBar, etc. // This setting is commonly overridden for skinning purposes. // @visibility external // @group appearance, footer // @example windowFooter //< showFooter:true, footerConstructor:"HLayout", //> @attr window.footerHeight (number : 18 : IR) // // The height of the footer, in pixels. // // @group appearance, footer // @visibility external //< footerHeight:18, //> @attr window.footerControls (Array of String : (see below) : IR) // Array of members to show in the Window footer. //

// The default value of footerControls is an Array of Strings listing the // standard footer controls in their default order: //

    //    footerControls : ["spacer", "resizer"]
    // 
// As with +link{Window.headerControls}, you can override footerControls // to change the order of standard controls in the footer. "spacer" is a special // value which will create a +link{LayoutSpacer} in the footer bar. "resizer" // will show the +link{window.resizer} in the footer. //

// By embedding a Canvas directly in this list you can add arbitrary additional controls to // the footer. //

// Note that the +link{window.statusBar} is not part of the set of footer controls - it is a // separate canvas rendered behind all footer controls. If you include some custom status bar // directly in the footerControls you may want to set +link{window.showFooter} to false. //

// Tip: custom controls need to set layoutAlign:"center" to appear vertically centered. // // @visibility external //< footerControls:["spacer", "resizer"], // StatusBar settings // ---------------------------------------------------------------------------------------- //> @attr window.statusBar (AutoChild : null : R) // Simple Canvas-based status bar, shown in the footer. +link{setStatus()} can be used to // show text here. // @visibility external //< //> @attr window.showStatusBar (boolean : true : [IRW]) // If true, show a statusBar for this Window, including resizer. // @visibility external // @group appearance, footer //< showStatusBar:true, statusBarConstructor:"Canvas", statusBarDefaults:{ overflow:isc.Canvas.HIDDEN, styleName:"windowStatusBar", addAsChild:true, width:"100%", wrap:false, leftPadding:5 }, // Resizer // -------------------------------------------------------------------------------------------- //> @attr window.resizer (AutoChild : null : R) // ImgButton-based resizer, shown in the footer. // @visibility external //< //> @attr window.showResizer (boolean : true : [IRW]) // If true, show a button in the lower right corner that allows users to resize the Window. // Note that the resizer will only be displayed if the footer is showing for the window // (+link{window.showFooter}) and +link{window.canDragResize} is true. // @group appearance, dragging // @visibility external //< showResizer:true, resizerConstructor:"Img", resizerDefaults:{ canDragResize:true, getEventEdge:function(){ if (this.creator.resizeFrom.contains("BR")) { return "BR"; } else if (this.creator.resizeFrom.contains("B")) { return "B"; } else if (this.creator.resizeFrom.contains("R")) { return "R"; } }, src:"[SKIN]/Window/resizer.gif", width:16, height:16 }, // Toolbar // ---------------------------------------------------------------------------------------------- // NOTE: only documented on Dialog showToolbar:false, toolbarConstructor:"Toolbar", toolbarDefaults:{ height:40, layoutMargin:10, membersMargin:5, overflow:"visible" }, // Edges // --------------------------------------------------------------------------------------- // show custom edges as a child Canvas, top and bottom only by default. customEdges:["T", "B"], // alternate mode where we create the edgedCanvas as a child and use layoutMargins to place // members. No known advantages. //edgesAsChild:true, // --------------------------------------------------------------------------------------- // set overflow to hidden; nothing should ever overflow the Window. We need to be overflow // "hidden" even if the body clips, since the Window can be minimized. overflow:"hidden" }); // END Window.addProperties() //!>Deferred isc.Window.addMethods({ //> @method Window.initWidget() (A) // Initialize this window. //< initWidget : function () { if (this.minimized && this.maximized) { this.logWarn("Window initialized with maximized and minimized both set to true. " + "This is unsupported. The Window will be rendered minimized."); this.maximized = false; } // If this.minimized is true, call this.minimize() to set up minimized height, etc. if (this.minimized) { // clear out the property to avoid any confusion (currently we don't have a no-op check // in there but we may introduce one at some point) this.minimized = null; this.minimize(); } else if (this.maximized) { this.maximized = null; this.maximize(); } /* // edges as child mode. Currently, no known advantages. if (this.showEdges) { var edge = this._createEdges(), edgesAsChild = this.edgesAsChild; // if edgesAsChild is true, we have no automatically created native margins, so we need // to use the Layout margin settings to cause our members (eg the header) not to // overlap the edges we are configured to show. if (edgesAsChild) { this.layoutLeftMargin = edge._leftMargin; this.layoutRightMargin = edge._rightMargin; this.layoutTopMargin = edge._topMargin; this.layoutBottomMargin = edge._bottomMargin; } } */ if (this.autoSize) { this.vPolicy = "none"; this.overflow = "visible"; } this.Super(this._$initWidget); // if we're not drawn, clear any specified items that are currently drawn // (Note: we could use 'addItems' to achieve this too) if (!this._isInitialized && this.items != null) { for (var i = 0; i < this.items.length; i++) { if (isc.isA.Canvas(this.items[i]) && this.items[i].isDrawn()) this.items[i].clear(); } } }, createChildren : function () { this.makeHeader(); // make the body of the Window, and set up the items in the Window as children of the body this.makeBody(); this.makeToolbar(); this.makeFooter(); this._isInitialized = true; }, makeToolbar : function () { this.addAutoChild("toolbar", { buttons:this.toolbarButtons, // hide initially if we're minimized visibility : this.minimized ? isc.Canvas.HIDDEN : isc.Canvas.INHERIT }); }, //> @method Window.draw() (A) // @group drawing // Override draw to create the various sub-components and arrange their zOrder appropriately // // @return (boolean) true if drawn successfully; false if not drawn for some reason //< draw : function (a,b,c,d) { if (isc._traceMarkers) arguments.__this = this; if (!this.readyToDraw()) return this; // create children (unless we've been clear()d and are being drawn for a second time) if (!this._isInitialized) this.createChildren(); // call the superclass draw to actually draw the components, including the body return this.invokeSuper(isc.Window, "draw", a,b,c,d); }, // Because we lazily add our items as children on draw, if we've never been drawn we will have // to explicitly destroy members of our items array. destroy : function () { if (!this._isInitialized) { var items = this.items; if (!isc.isAn.Array(items)) items = [items]; for (var i = 0; i < items.length; i++) { if (isc.isA.Canvas(items[i])) items[i].destroy(); } } this.items = null; this.destroyModalMask(); return this.Super("destroy", arguments); }, // Bring Windows to front on mouseUp. mouseUp : function () { this.bringToFront(); this.Super("mouseUp", arguments); }, // Header Methods // ----------------------------------------------------------------------------------------------- // These are methods that construct the header. Window.setHeader() is the main method. // It calls the make() methods of its constituent components to set them up and lay // them out. // // declare relationships of children of header autoChildParentMap : { resizer : "footer", statusBar : "footer", headerBackground : "header", headerIcon : "header", headerLabel : "header", minimizeButton : "header", maximizeButton : "header", closeButton : "header", toolbar : "body" }, //> @method window.setHeader() // @group appearance // initialize the header and its components. // if placement parameters are given, then lay out the header. // // @param left (number) left position of header // @param top (number) right position of header // @param width (number) width of header // @param height (number) height of header //< makeHeader : function () { // the header is first created, then its children. var header = this.addAutoChild("header", {styleName:this.headerStyle}); if (header == null) return; // not showing a header // create children once the header has been created if (header != null) { var headerBackground = this.addAutoChild("headerBackground", { // src will be picked up only by an Img/StretchImg src:this.headerSrc }); if (headerBackground) headerBackground.sendToBack(); // if the window is in minimized state before we draw, swap in the restore button // autoChild defaults so we get the restore button to draw instead. if (this.minimized) { this._minimizeButtonDefaults = this.minimizeButtonDefaults; this._minimizeButtonProperties = this.minimizeButtonProperties; this.minimizeButtonDefaults = this.restoreButtonDefaults; this.minimizeButtonProperties = this.restoreButtonProperties; // Ditto with the maximize button } else if (this.maximized) { this._maximizeButtonDefaults = this.maximizeButtonDefaults; this._maximizeButtonProperties = this.maximizeButtonProperties; this.maximizeButtonDefaults = this.restoreButtonDefaults; this.maximizeButtonProperties = this.restoreButtonProperties; } // instantiate the header buttons in left-> right order so the tab order is appropriate // when we allow tabbing through them. this.addAutoChildren(this.headerControls, this.header); if (this.minimized) { this.minimizeButtonDefaults = this._minimizeButtonDefaults; this.minimizeButtonProperties = this._minimizeButtonProperties; this._minimizeButtonDefaults = this._minimizeButtonProperites = null; } else if (this.maximized) { this.maximizeButtonDefaults = this._maximizeButtonDefaults; this.maximizeButtonProperties = this._maximizeButtonProperties; this._maximizeButtonDefaults = this._maximizeButtonProperites = null; } } }, setHeaderControls : function (headerControls) { if (this.headerControls == headerControls) return; var oldHeaderControls = this.headerControls, oldControls = []; this.headerControls = headerControls; if (this.header == null) return; for (var i = i ; i < oldHeaderControls.length; i++) { // map from auto child names ('minimizeButton' etc) to live widgets if (isc.isA.String(oldHeaderControls[i])) oldControls[i] = this[oldHeaderControls[i]] else oldControls[i] = oldHeaderControls[i]; } this.header.removeMembers(oldControls); this.header.addMembers(headerControls); }, // The way auto-children work is that if show[childName] is false, they aren't created as // part of addAutoChild() // This means that simply setting the show[headerControl] attributes after initial call to // makeHeader will fail to ever create / show these controls. // Therefore have a method to explicitly create and show the header controls at runtime setShowHeaderControl : function (controlName, show, showControlAttrName) { var headerControls = this.headerControls; if (!headerControls.contains(controlName)) { this.logWarn("request to show/hide header control with name:" + controlName + ". No such control is present in this.headerControls - ignoring."); return; } if (!showControlAttrName) showControlAttrName = "show" + controlName.substring(0,1).toUpperCase() + controlName.substring(1); if (this[showControlAttrName] == show) return; this[showControlAttrName] = show; // If we've never created our header - don't worry - our headerControls will be updated // if/when we do create the header if (this.header == null) return; if (this[controlName]) { if (show) this[controlName].show(); else this[controlName].hide(); } else if (show) { var slot = 0; for (var i = 0; i < headerControls.length; i++) { if (headerControls[i] == controlName) break; if (this[headerControls[i]]) slot++; } this.addAutoChild(controlName, null, null, this.header, slot); this[controlName].show(); } }, //> @method Window.setShowCloseButton() // Dynamically update +link{window.showCloseButton} to show / hide the closeButton // @see window.headerControls // @see window.showCloseButton // @visibility external //< setShowCloseButton : function (show) { this.setShowHeaderControl("closeButton", show, "showCloseButton"); }, //> @method Window.setShowMinimizeButton() // Dynamically update +link{window.showMinimizeButton} to show / hide the minimizeButton // @see window.headerControls // @see window.showMinimizeButton // @visibility external //< setShowMinimizeButton : function (show) { this.setShowHeaderControl("minimizeButton", show, "showMinimizeButton"); }, //> @method Window.setShowMaximizeButton() // Dynamically update +link{window.showMaximizeButton} to show / hide the maximizeButton // @see window.headerControls // @see window.showMaximizeButton // @visibility external //< setShowMaximizeButton : function (show) { this.setShowHeaderControl("maximizeButton", show, "showMaximizeButton"); }, //> @method Window.setShowHeaderIcon() // Dynamically update +link{window.showHeaderIcon} to show / hide the headerIcon // @see window.headerControls // @see window.showHeaderIcon // @visibility external //< setShowHeaderIcon : function (show) { this.setShowHeaderControl("headerIcon", show, "showHeaderIcon"); }, getDynamicDefaults : function (childName) { if (isc.endsWith(childName, isc.Button.Class)) { return { canFocus : this.canFocusInHeaderButtons }; } }, // custom autoChild maker function for the headerLabel, because it is currently wrapped inside // a Canvas used for clipping headerLabel_autoMaker : function () { // if we're not showing a headerLabel, if (!this.showTitle) { // clear the headerLabel property this.headerLabel = null; // and get outta dodge return; } var headerLabelParent = isc.Canvas.create({ autoDraw:false, _generated:true, contents: isc.Canvas.blankImgHTML(1000,100), overflow:"hidden" }); var dragRepo = this.canDragReposition; // if the Window is moveable, make the header draggable if (dragRepo) { headerLabelParent.canDragReposition = true; headerLabelParent.dragTarget = this; // HACK: for a Window, canDragReposition means you can reposition using the header. We // have to turn it off for the widget as a whole or any widget that lets drag events // bubble will cause strange effects. this.canDragReposition = false; } var headerLabel = this.headerLabel = this.createAutoChild( "headerLabel", { height:"100%", contents:this.title, dragTarget:this, // Override getCurrentCursor so we show the drag reposition cursor // rather than the default pointer. getCurrentCursor : function () { if (this.parentElement) return this.parentElement.getCurrentCursor(); return this.Super("getCurrentCursor", arguments); } }); headerLabelParent.addChild(headerLabel); this.header.addMember(headerLabelParent); }, //> @method Window.setTitle() ([]) // Sets the title text that appears in the window header; the header will be redrawn // if necessary. // @visibility external // @group header // @param newTitle (string : null) new title //< setTitle : function (newTitle) { if (newTitle) this.title = newTitle; if (!this.header) return; // if a header label exists, set the title on that, otherwise set it on the header if (this.headerLabel) this.headerLabel.setContents(this.title); else this.header.setContents(this.title); }, // Toolbar Methods // ----------------------------------------------------------------------------------------------- // These are methods that construct the toolbar. // //> @method dialog.setButtons() // Set the buttons for the toolbar displayed in this dialog. // Synonym for +link{dialog.setToolbarButtons()} // @param newButtons (array of Buttons: null) buttons for the toolbar // @visibility external //< setButtons : function (newButtons) { return this.setToolbarButtons(newButtons); }, // Exposed at the Dialog level, where we also expose the toolbarButtons attribute //> @method dialog.setToolbarButtons() // Set the +link{dialog.toolbarButtons} for this dialog. // Synonym for +link{dialog.setButtons()}. // @param newButtons (array of Buttons: null) buttons for the toolbar // @visibility external //< setToolbarButtons : function (newButtons) { this.toolbarButtons = newButtons; if (this.toolbar) this.toolbar.setButtons(newButtons); }, // Footer Methods // ----------------------------------------------------------------------------------------------- // These are methods that construct the footer. Window.setFooter() is the main method. // It calls the make() methods of its constituent components to set them up and lay // them out. // //> @method window.setFooter() // @group appearance // initialize the footer and its components. // if placement parameters are given, then lay out the footer. // // @param left (number) left position of footer // @param top (number) right position of footer // @param width (number) width of footer // @param height (number) height of footer //< makeFooter : function () { // if not showing a footer, bail if (!this.showFooter) return; this.addAutoChild("footer", {height:this.footerHeight}); if (!this.footer) return; var controls = []; for (var i = 0; i < this.footerControls.length; i++) { var control = this.footerControls[i], properties = {}; if (control == "spacer") control = isc.LayoutSpacer.create(); if (control == "resizer") { if (!this.canDragResize) continue; properties.dragTarget = this; } properties.visibility = this.minimized ? isc.Canvas.HIDDEN : isc.Canvas.INHERIT; if (isc.isA.String(control)) { this.addAutoChild(control, properties, null, this.footer); } else { if (isc.isA.Canvas(control)) control.setProperties(properties); else isc.addProperties(control, properties); this.footer.addMember(control); } } // status bar fills entire width (not a member: extends under resizer) // Note that this means the resizer may obscure the borders of the statusBar. This is // currently handled by the resizer media this.addAutoChild("statusBar", { height: this.footer.getHeight(), visibility : this.minimized ? isc.Canvas.HIDDEN : isc.Canvas.INHERIT }); if (this.status != null) this.setStatus(this.status); this.statusBar.sendToBack(); }, //> @attr Window.status (string : null : IRW) // Text to show in the status bar of the window (if one is visible) // @group appearance // @visibility external //< //> @method Window.setStatus() ([]) // Sets the text in the status bar of the window, redrawing if necessary. // @param statusString (string) new text for the status bar // @group appearance // @visibility external //< setStatus : function (statusString) { this.status = statusString; if (this.statusBar == null) return; if (statusString == null) statusString = ""; var leftPadding = (this.statusBar.leftPadding ? isc.Canvas.spacerHTML(this.statusBar.leftPadding,1) : ""); this.statusBar.setContents(leftPadding + statusString); }, //> @method Window.setSrc() ([]) // Sets the URL of the contents to display in the body of the window, redrawing if // necessary. // @visibility external // @group appearance, body // @param url (string) URL of new contents to be displayed in the window body //< setSrc : function (url) { this.src = url; if (this.body) this.body.setContentsURL(url); }, // Misc Make Methods // ----------------------------------------------------------------------------------------------- // make methods for the body // //> @method Window.makeBody() (A) // @group appearance, body // make the body of the Window //< makeBody : function() { // if not showing the body, bail if (!this.showBody) return; // Body contents can be assigned using the following methods: // - The src property can be set to a URL. this will be assigned to the body // canvas' contentsURL property. // - The items property can be set to a string. this will be assigned to the // contents property of the body canvas. // - The items property can be set to an existing canvas or an array of canvases. // These will be assigned as the body canvas' children. var children, contents, contentsURL; if (this.src) { contentsURL = this.src; } else { // determine whether to display the window contents as contents or children of the body // canvas var items = this.items; if (isc.isA.Array(items)) { // contents are Canvii - duplicate the Array to keep body.children as a distinct // array from this.items. children = items.duplicate(); } else if (isc.isA.Canvas(items)) { // contents is a single Canvas children = items; } else { // contents is HTML content contents = items; } // For the AutoTest module, mark each item as a locationChild of the window // (This could also be achieved via a call to addItems or similar if (!isc.isAn.Array(items)) items = [items]; for (var i = 0; i < items.length; i++) { if (isc.isAn.Object(items[i])) items[i].locatorParent = this; } } // if the bodyConstructor hasn't been set, use the appropriate constructor based on // the kind of content we have: // - contentsURL: use an HTMLFlow // - contents (as a string): use a Canvas // - children // - if autoSizing, or explicit contentLayout, use a Layout // - otherwise use a Canvas if (!this.bodyConstructor) { if (contentsURL) { // body will be a normal Canvas (containing an IFrame if contentsURL specified) this.bodyConstructor = "HTMLFlow"; } else if (contents) { this.bodyConstructor = "Canvas"; } else if (!this.autoSize) { // if the Window dictates body size, and contentLayout hasn't been set to none, use // a Layout if (this.contentLayout != "none") this.bodyConstructor = "Layout"; // if contentLayout is set to none, use a Canvas else this.bodyConstructor = "Canvas"; } else { // use a Layout with a none/none policy for autoSize:true // so that contents will not be resized when they're first drawn // when the window is drag resized, the body's policy will be set to fill/fill this.bodyConstructor = "Layout"; var policyProps = {vPolicy:"none", hPolicy:"none"}; if (!this.bodyProperties) this.bodyProperties = policyProps; else isc.addProperties(this.bodyProperties, policyProps); } } // NOTE: create items instead of allowing it to happen as the body initializes its children // array, so that any autoChildren are created in the context of the Window itself, not the // body this.createCanvii(children); if (isc.Browser.isMoz && contentsURL != null) { if (!this.body) this.body = {}; this.body.useClipDiv = false; } // create the body canvas var bodyProps = ("body", { contents : contents || " ", // XXX watch tab can't handle showing non-generated children of generated components. // We should fix that. For now, just flag the body as non-generated _generated: false, defaultHeight : this.autoSize ? 50 : 100, contentsURL : contentsURL, contentsType : this.contentsType, hideUsingDisplayNone: (isc.Browser.isMoz && contentsURL ? true : false), styleName : this.bodyStyle, backgroundColor : this.bodyColor, // hide initially if we're minimized visibility : this.minimized ? isc.Canvas.HIDDEN : isc.Canvas.INHERIT, // for when the body is a Layout/Stack vertical : (this.contentLayout == isc.Canvas.VERTICAL), // when Window size dictates body size, scroll as needed. Otherwise, expand to body // contents overflow:this.autoSize ? "visible" : "auto" }); // should the window.items become members or children of the body? var bodyClass = isc.ClassFactory.getClass(this.bodyConstructor); if (bodyClass && bodyClass.isA("Layout")) { bodyProps.members = children; } else { bodyProps.children = children; } this.addAutoChild("body", bodyProps); }, setBodyColor : function (color) { this.bodyColor = color; if (this.body) this.body.setBackgroundColor(color) }, hasInherentHeight : function () { return this.autoSize; }, hasInherentWidth : function () { return this.autoSize; }, //> @method Window.addItem() ([A]) // Adds a widget to the body area of the window. // @visibility external // @group windowItems // @param item (Canvas) the widget to be added // @return (array) array of widgets added //< addItem : function (item, position) { return this.addItems([item], position); }, //> @method Window.removeItem() ([A]) // Removes a widget from the body area of the window. // @visibility external // @group windowItems // @param item (Canvas) the widget to be removed // @return (array) the array of widgets removed //< removeItem : function (item) { return this.removeItems([item]); }, //> @method Window.addItems([A]) // Adds an array of widgets to the window. // @visibility external // @group windowItems // @param items (Array of Canvas) an array of widgets to be added // @return (array) array of widgets added //< addItems : function (items, position) { if (!isc.isAn.Array(items)) items = [items]; if (!this.items) this.items = []; for (var i =0; i < items.length; i++) { // handle calling code that passes null or undefined if (!items[i]) continue; // Skip any items we already have if (this.items.contains(items[i])) continue; // add each item to this.items if (position != null) this.items.addAt(items[i], position+i); else this.items.add(items[i]); // Explicitly flag this widget as the locatorParent of the widget - used by the // AutoTest module items[i].locatorParent = this; // if the body hasn't been created yet, ensure any drawn items are clear()'d, and return if (!this._isInitialized) { if (isc.isA.Canvas(items[i]) && items[i].isDrawn()) items[i].clear(); // If the body has been drawn - add the items to it as members/children } else { // Depending on the contentLayout property the body may be a layout or a straight // canvas. Use addMember if it's there, otherwise just addChild. if (this.body.addMember) { this.body.addMember(items[i], position != null ? position+i : null); } else { this.body.addChild(items[i]); } } } return items; }, //> @method Window.removeItems([A]) // Removes an array of widgets from the window. // @visibility external // @group windowItems // @param items (array of canvases) an array of widgets to be removed // @return (array) the array of widgets removed //< removeItems : function (items) { if (!isc.isAn.Array(items)) items = [items]; for (var i = 0; i < items.length; i++) { delete items[i].locatorParent; } if (this._isInitialized) { if (this.body.removeMembers) this.body.removeMembers(items); else { for (var i=0; i @method window.addMember() [A] // Same as +link{layout.addMember()}. Note that in order to add items to +link{window.body}, // you use +link{window.addItem()} rather than addMember. Adding a member to // a Window adds the member as a sibling to the header, body and other built-in Window // subcomponents. // @include layout.addMember() // @visibility external //< //> @method window.addMembers() [A] // Same as +link{layout.addMembers()}. Note that in order to add items to +link{window.body}, // you use +link{window.addItem()} rather than addMembers. Adding a member to // a Window adds the member as a sibling to the header, body and other built-in Window // subcomponents. // @include layout.addMembers() // @visibility external //< // Resizing / Layout // --------------------------------------------------------------------------------------- // override to handle autoSize:true: make the Window match the body's size layoutChildren : function (a,b,c,d) { if (this.body == null) return; if (this._disableAutoSize) { this._disableAutoSize = null; this.disableAutoSize(); } if (this.autoSize) this._matchBodyWidth(); this.invokeSuper(isc.Window, "layoutChildren", a,b,c,d); var edge = this.edgesAsChild ? this._edgedCanvas : null; if (edge) edge.setHeight(this.getVisibleHeight(true)); }, _matchBodyWidth : function () { if (this.minimized) return; if (this._matchingWidth) return; this._matchingWidth = true; var edge = this.edgesAsChild ? this._edgedCanvas : null; if (!this.body.isDrawn()) this.body.draw(); // if autoSizing, once the body has received an initial width from the Window, don't have // the Window's layout code manage the width of the body. Otherwise, the first time we // autoSize to an overflowed body, we'll size the body to it's overflow'd size, // establishing the overflowed size as a minimum from then on. this.body.inherentWidth = true; // the window should be larger than the body by styling width (margin/border/padding) on // Window as a whole, plus the layoutMargin, which is interior to styling. var edgeWidth = (this.getWidth() - this.getInnerWidth()) + this._leftMargin + this._rightMargin; // plus the width of rounded edges, if edges are done as a child (otherwise these are // already factored in as native margins) if (edge) edgeWidth += edge._leftMargin + edge._rightMargin; var windowWidth = this.body.getVisibleWidth() + edgeWidth; this.logInfo("edgeWidth is: " + edgeWidth + ", setting window width to: " + windowWidth, "layout"); // setting the Window's width to match the body means all other children (eg the header) // will be sized to match the Window's width if (this.getWidth() != windowWidth) this.setWidth(windowWidth); this._matchingWidth = null; }, disableAutoSize : function () { this.setAutoSize(false); }, //> @method window.setAutoSize() // Setter for +link{window.autoSize} // @param autoSize (boolean) true if the window should auto-size to its content // @visibility external //< setAutoSize : function (autoSize) { this.autoSize = autoSize; if (autoSize) { if (this.body) { // set the body to apply a "fill" policy if its a Layout (in autoSize mode we just // stack the body items by default) if (isc.isA.Layout(this.body)) this.body.vPolicy = this.body.hPolicy = "none"; // set the body to start scrolling this.body.setOverflow("visible"); } // change the policy of the Window as a whole to start setting the size of the body // based on the Window size instead of vice versa this.vPolicy = "none"; this.setOverflow("visible"); } else { if (this.body) { // set the body to apply a "fill" policy if its a Layout (in autoSize mode we just // stack the body items by default) if (isc.isA.Layout(this.body)) this.body.vPolicy = this.body.hPolicy = "fill"; // set the body to start scrolling this.body.setOverflow("auto"); this.body.inherentWidth = false; } // change the policy of the Window as a whole to start setting the size of the body // based on the Window size instead of vice versa this.vPolicy = "fill"; this.setOverflow("hidden"); } }, // if we are dragResized, disable autoSizing dragResizeStart : function () { if (this.Super("dragResizeStart", arguments) == false) return; // set a flag to disable autoSizing the next time we do layout. // NOTE: technically, we should only do this on a successful drag, and for the special case // of dragAppearance target, be able to disable autoSizing but re-enable it on drag // cancellation. if (this.autoSize && isc.EH.dragTarget == this) { this.autoSize = false; this._disableAutoSize = true; } }, // --------------------------------------------------------------------------------------- //> @method Window.returnValue() // @group data // return a value to the callback function // and hide the Window // // @param value (any) return value for the Window //< returnValue : function (value) { if (this.isVisible()) this.hide(); if (this.callback) { //this.fireCallback(this.callback, "value", [value]); // the above call needs to be delayed to prevent a bug where subsequent dialogs shown // from the callback aren't shown when the cancel button is pressed. this.delayCall("fireCallback", [this.callback, "value", [value]], 50); } return value; }, // event handling // ------------------------------------------------------------------------------------------------- // //> @method Window.show() // Show the Window. //

// When a modal window is shown, it will begin blocking input to any components on the screen other // than the modal window. // @group appearance //< show : function (a,b,c,d) { if (isc._traceMarkers) arguments.__this = this; if (this.isModal) { // 2 kinds of modality: // - modalTarget: mask everything within the modal target, link visibility to modalTarget // - no modal target: show global clickMask and bring us above it. if (this.modalTarget) { if (!isc.isA.Canvas(this.modalTarget) || this.modalTarget.contains(this)) { this.logWarn("Invalid modalTarget:" + this.modalTarget + ". Should be a canvas, and not an ancestor of this Window."); delete this.modalTarget; this.isModal = false; } else { this.modalTarget.showComponentMask( this.showModalMask ? {styleName: this.modalMaskStyle, opacity: this.modalMaskOpacity } : null ); this.observeModalTarget(); } // Explicitly catch the case of a developer specifying isModal on a non top-level window // this will be clearer than a log message about clickMasks. } else if (this.topElement != null) { this.logWarn("Window specified with 'isModal' set to true, but this window has a " + "parentElement. Only top level Windows can be shown modally."); this.isModal = false; } else { this.showClickMask( this.getID() + (this.dismissOnOutsideClick ? ".handleCloseClick()" : ".flash()"), false, // Don't mask ourselves [this]); this.makeModalMask(); } } // If we're going to be auto-centered, draw offscreen before centering if (this.autoCenter && !this.parentElement) { this._centering = true; this.moveTo(0, -1000); this._centering = false; } this.invokeSuper(isc.Window, "show", a,b,c,d); if (this.autoCenter) { // if we're supposed to autoCenter, center in the page this.centerInPage(); // set up an event to keep autoCentering on page resize if (!this.parentElement) { isc.Page.setEvent(this._$resize, this, null, "parentResized"); } } this.bringToFront(); }, makeModalMask : function () { if (!this.showModalMask) return; if (!this.modalMask) this.modalMask = this.createAutoChild( "modalMask", { styleName: this.modalMaskStyle, opacity: this.modalMaskOpacity } ); this.modalMask.show(); }, hideModalMask : function () { if (this.modalMask) this.modalMask.hide(); }, destroyModalMask : function () { if (this.modalMask) { this.modalMask.destroy(); this.modalMask = null; } }, // Modal target behavior // ---------------------------- // if we have a modal target, hide and show / draw and clear with it observeModalTarget : function () { if (this._modalTargetVisibilityChange) return; this.observe(this.modalTarget, "show", "observer.modalTargetVisibilityChanged(observed)"); this.observe(this.modalTarget, "hide", "observer.modalTargetVisibilityChanged(observed)"); this.observe(this.modalTarget, "clear", "observer.modalTargetVisibilityChanged(observed)"); this.observe(this.modalTarget, "draw", "observer.modalTargetVisibilityChanged(observed)"); this.observe(this.modalTarget, "parentVisibilityChanged", "observer.modalTargetVisibilityChanged(observed)"); }, ignoreModalTarget : function () { if (this._modalTargetVisibilityChange) return; this.ignore(this.modalTarget, "show"); this.ignore(this.modalTarget, "hide"); this.ignore(this.modalTarget, "draw"); this.ignore(this.modalTarget, "clear"); this.ignore(this.modalTarget, "parentVisibilityChanged"); }, modalTargetVisibilityChanged : function (modalTarget) { // set special flag b/c we don't want the hide()/show() calls resulting from our call here // to to unregister the observations. this._modalTargetVisibilityChange = true; if (modalTarget.isVisible() && modalTarget.isDrawn()) this.show(); else this.hide(); delete this._modalTargetVisibilityChange; }, //> @method window.shouldDismissOnEscape() // Should this window be dismissed (same effect as pressing the "Cancel" button) when the // user presses the "Escape" key?
// Default behavior: if +link{window.dismissOnEscape} is set, just return it. Otherwise return // true if this window is showing a "close" control in the header // (see +link{window.headerControls}). // @return (boolean) true if the window should be dismissed when the user hits escape // @visibility external //< shouldDismissOnEscape : function () { if (this.dismissOnEscape != null) return this.dismissOnEscape; // If we're showing a close button in our header, return true return this.showHeader && this.headerControls && this.showCloseButton && this.headerControls.contains("closeButton"); }, // Implement dismissOnEscape via the bubbled keyPress event. // This means that if we don't contain focus, or if "Escape" has meaning to a child (EG LG Editing/ // modal windows) we won't get the event and kill the window. handleKeyPress : function () { var keyName = isc.EH.getKey(); if (keyName == "Escape" && this.shouldDismissOnEscape()) { this.handleEscape(); return false; } return this.Super("handleKeyPress", arguments); }, // handleEscape() - fired when the user hits escape if 'dismissOnEscape' is true. // Fires closeClick() to dismiss the window. Can potentially be overridden for other // behavior. handleEscape : function () { // If we're under a clickMask, don't dismiss. // This handles the case where we're showing 2 windows, the top one of which is modal // In this case we want the user to have to interact with the top window before // dismissing the window underneath it. if (this.isMasked()) return; this.handleCloseClick(); }, resized : function (a,b,c,d) { this.invokeSuper(isc.Window, "resized", a,b,c,d); if (this.autoCenter) this.centerInPage(); }, //> @method Window.hide() // Hide the Window. Hides the clickMask for modal Windows. // @group appearance //< hide : function (a,b,c,d) { //>Animation if (this._animatingMinimize) isc.Animation.finishAnimation(this._animatingMinimize); // @method Window.clear() // When clearing a modal window, also clear the clickMask // @group appearance //< clear : function (a,b,c,d) { //>Animation if (this._animatingMinimize) isc.Animation.finishAnimation(this._animatingMinimize); // @method Window.centerInPage() ([A]) // Centers the Window in the page. This is called automatically in window.show() if // Window.autoCenter is true. // Note - if the Window is a child of another widget, we center in the parent widget // rather than centering in the page. // @visibility external // @group appearance // @see autoCenter //< centerInPage : function () { var width = this.getVisibleWidth(), height = this.getVisibleHeight(), parent = this.parentElement ? this.parentElement : isc.Page, left = ((parent.getWidth() - width) / 2) + parent.getScrollLeft(), top = ((parent.getHeight() - height) / 2) + parent.getScrollTop(); // Don't try to apply decimal positions, don't position top of window off-screen left = Math.round(left); top = Math.max(Math.round(top),0); this._centering = true; this.moveTo(left, top); this._centering = null; }, // Miscellaneous methods // ------------------------------------------------------------------------------------------------- // //> @method Window.flash() ([A]) // Makes the window header flash if it's visible; if there's no header, or the header // is hidden, makes the window body flash instead. //

// This method is executed when users click outside the bounds of a modal window // so they'll notice that they have to do something with the window. // @visibility external // @group modal //< flash : function (step) { var showHeader = this.showHeader; if (step == null) { // kick off a new flashing cycle // Set a 'isFlashing' flag, so we don't attempt to start a new flashing cycle in the // middle of a running one. if (this._isFlashing) return false; // return false to cancel the click this._isFlashing = true; step = 0; // store off the starting styleNames/backgroundColors/Img sources. NOTE: if (showHeader) { this._headerStyle = this.header.getStateName(); if (this.headerBackground) { this._headerBGStyle = this.headerBackground.getStateName(); this._headerBGSrc = this.headerBackground.src; } } else { this._bodyColor = this.body.backgroundColor; } } if (showHeader) { // apply the original or flash styles / sources in alternation var newStyle = (step % 2 == 0 ? this.hiliteHeaderStyle : this._headerStyle), newSrc = (step % 2 == 0 ? this.hiliteHeaderSrc : this._headerBGSrc), newBGStyle = (step % 2 == 0 ? this.hiliteHeaderStyle : this._headerBGStyle); this.header.setStyleName(newStyle) var background = this.headerBackground; if (background) { this.headerBackground.setStyleName(newBGStyle) if (background.setSrc) background.setSrc(newSrc); } } else { // if there's no header, flash the body var newColor = (step % 2 == 0 ? this.hiliteBodyColor : this._bodyColor); this.body.setBackgroundColor(newColor); } step++; if (step < 4) this.delayCall("flash", [step], 100); else this._isFlashing = false; // clear the isFlashing flag return false; // return false to cancel the click }, //> @method Window.minimize() // Minimize the window. Fired when the user clicks the minimize button if // +link{window.showMinimizeButton, this.showMinimizeButton} is true.
// Default implementation shrinks the window to just the height of the header bar, hiding the // body. If +link{window.animateMinimize, animateMinimize} is true, the resize will be animated. // A restore button will be displayed in place of the minimize button when the window is // minimized. // @visibility external //< minimize : function () { // This will hide everything except the header, and size the window to match the header's // height. //>Animation if (this._animatingMinimize) isc.Animation.finishAnimation(this._animatingMinimize); //Animation this._minimizeHeight = minimizeHeight; if (this.animateMinimize && this.isDrawn() && this.isVisible()) { if (minButton) { minButton.disable(); minButton.redraw(); } // Remember the sizing / overflow of the body for when we're done minimizing this._storeContentRestoreStats(); // Note: we use the same flag for minimize and restore animation IDs since the same // actions (show/hide/resize/minimize/restore) all kill the animation this._animatingMinimize = isc.Animation.registerAnimation(this.animateMinimizeStep, (this.minimizeTime||this.animateTime), this.minimizeAcceleration || this.animateAcceleration, this); } else { //Animation }//





© 2015 - 2024 Weber Informatics LLC | Privacy Policy