<@doc hierarchy="GMLDOM"> Represents layout widget that participates in the layout of the screen, such as Interactor and Container. Such object can typically have Title bar, Toolbar and Paging bar, as well as object-specific Contents area. (c) SAP AG 2003-2006. All rights reserved. #ALIAS[l=core.lyt:Layout] Aspect Box for Layout; inherit Widget; override virtual property type = 'box'; virtual property features = { className: null ,title: true, titleClass: 'BOX-TTLBAR' ,toolbar: false ,formRulers:false ,pagbar: false, pagbarClass: 'BOX-NAVBAR' ,contents: true, contentsClass: 'BOX-CONTENT' ,selector: false, selectorClass: 'VIEWBAR' }; ///////////////////////////////////////////////////////////////////////////////////// // Overrides constructor(board, parent) this.supercall(); this.ttlbar = null; this.vRulers = null; this.hRulers = null; this.cellObject = null; this.toolbarID = null; this.pagbar = null; this.contents = null; this.border = null; this.selector = null; this.selectionRow = null; end virtual method getToolbar() return this.board.getWidget(this.toolbarID); end override virtual method paint(parentElement) try { this.supercall(); var F = RULE('defineWidget', this.board.rtSkin, base); if (!F) return; this.features = F; var elem = this.createHtmlElement('DIV', F.className||null, this.id, this.parentElement); elem.title = base.getTitle(true); // NOTE: remove DOM dependencies (replace by 'nameKey'). Here and everywhere elem.gs = this.board.gridSize; this.elem = elem; if (F.toolbar && base.toolbar) { var toolbar = $DOM.createAspect('#NS[Layout]', base.toolbar, this.board, this); if (toolbar) { this.toolbarID = toolbar.id; toolbar.paint(); } } this.ttlbar = F.title ? this.createHtmlElement('DIV', F.titleClass||null, null, elem) : null; this.pagbar = F.pagbar ? this.createHtmlElement('DIV', F.pagbarClass||null, null, elem) : null; if (F.selector) { this.selector = this.createHtmlElement('DIV', F.selectorClass, null, elem); $ENV.createObject(F.selectorMgr, this.board, this, this.selector, true); } if (F.contents) { this.contents = this.createHtmlElement('DIV', F.contentsClass||null, null, elem); this.contents.id = 'BOX_' + this.id; // ALL BOX's HTML ID WILL HAVE THE FORMAT : BOX_[GML_ID] --> Very Importent var scrollElem = ISA(base, 'gml2:Interactor') ? this.contents : this.elem; scrollElem.onscroll = makeEventHandler(this, this.reselectContents); if (F.formRulers) { this.cellObject = this.createHtmlElement('SPAN', 'FORMCELL', null, this.contents); this.hideCellSelection(); this.vRulers = []; this.hRulers = []; var len = base.is1FixMode() ? 1 : base.columns - 1; for (var i=0; i len1_) { for (; i len2_) { for (; i Resizes box features after box resize or feature visibility change virtual method resizeFeatures() var width = this.elem.offsetWidth; var height = this.elem.offsetHeight; var toolbar = this.getToolbar(); var titleHeight = this.ttlbar ? this.ttlbar.offsetHeight||0 : 0; var toolbarHeight = (toolbar && base.showToolbar) ? toolbar.defaultHeight||0 : 0; // NOTE: DOM dependency var selectorHeight = this.selector ? this.selector.offsetHeight||0 : 0; var pagbarHeight = this.pagbar ? this.pagbar.offsetHeight||0 : 0; var y = 0; var h = height; if (toolbar && toolbarHeight) { var toolbarSize = SPLIT(toolbar.base.size); var uHeight = INT(toolbarSize[1]||0); if (uHeight > toolbarHeight) toolbarHeight = uHeight; } if (this.ttlbar && base.showTitlebar) { this.ttlbar.style.width = width; y += titleHeight; h -= titleHeight; } if (this.pagbar && base.showPagingbar) { this.pagbar.style.top = height - pagbarHeight; this.pagbar.style.width = width; h -= pagbarHeight; } if (toolbar && toolbarHeight) { if (toolbar.base.dock != 'bottom') { // TODO: DOM dependency toolbar.setRect({x: 0, y: y, w: width, h: toolbarHeight}); y += toolbarHeight; h -= toolbarHeight; } else { h -= toolbarHeight; toolbar.setRect({x: 0, y: MAX(y + h - 1, 0), w: width, h: toolbarHeight + 1}); toolbarHeight = 0; } } if (this.selector) { this.selector.style.top = y; this.selector.style.width = width; y += selectorHeight; h -= selectorHeight; } h = MAX(h, 0); if (this.contents) { var cst = this.contents.style; cst.top = y; // Resize row selection row if exsists if (this.selectionRow) { var selectionWidth = this.getContentsLeftGap(); cst.left = selectionWidth; cst.width = width - selectionWidth; this.selectionRow.style.top = toolbarHeight + titleHeight ? toolbarHeight + titleHeight : (base.showHeading ? #[LYT_COLUMN_HEAD_HEIGHT] : 0); this.selectionRow.style.display = selectionWidth ? 'block' : 'none'; } else cst.width = this.calcContentsW(width); cst.height = this.calcContentsH(h); } if (this.addition) this.addition['width'] = width; end <@method name="repaintPagbar"> Repaints the navigation (paging) bar virtual method repaintPagbar() var pagbar = base.pagbar; // TODO: DOM dependency if (!this.pagbar || !pagbar) return; var bar = []; var flags = SPLIT(pagbar); for (var i=0, len=flags.length; i0/0'); if (flags.pageLevel || flags.rowLevel) { bar.push(''); if (flags.pageLevel) add('GOTO(FIRST)', '#URL[~res:skins.neutral.images.first_page_1.gif]'); if (flags.pageLevel) add('GOTO(PREV)', '#URL[~res:skins.neutral.images.prev_page_1.gif]'); if (flags.rowLevel) add('SELECT(PREV)', '#URL[~res:skins.neutral.images.prev_row_1.gif]'); bar.push(''); bar.push(''); if (flags.rowLevel) add('SELECT(FIRST)', '#URL[~res:skins.neutral.images.next_row_1.gif]'); if (flags.pageLevel) add('GOTO(NEXT)', '#URL[~res:skins.neutral.images.next_page_1.gif]'); if (flags.pageLevel) add('GOTO(LAST)', '#URL[~res:skins.neutral.images.last_page_1.gif]'); bar.push(''); } if (flags.addRows || flags.delRows || flags.moveRows) { bar.push(''); if (flags.addRows) add('INSERT(AFTER)', '#URL[~res:skins.neutral.images.add_row_1.gif]'); if (flags.delRows) add('DELETE', '#URL[~res:skins.neutral.images.del_row_1.gif]'); if (flags.moveRows) add('MOVE(BEFORE)', '#URL[~res:skins.neutral.images.move_up_1.gif]'); if (flags.moveRows) add('MOVE(AFTER)', '#URL[~res:skins.neutral.images.move_dn_1.gif]'); bar.push(''); } this.pagbar.innerHTML = bar.join(''); function add(action, icon) { bar.push(''); } end override virtual method applyLayout(focusWidget, operation, repaint) if (this.isRendered) { this.isRendered = false; return false; } this.isRendered = true; try { var returnData = this.applyToolbarLayout(focusWidget, operation); repaint |= returnData.repaint; // GridView only if (typeof this.checkRows == 'function') this.checkRows(operation, true); if (returnData.skipParent) return false; repaint |= this.layoutContents(focusWidget, operation); this.board.adjustSelection(); } catch (e) { #LOG[2, 'Failed to applyLayout for ' + (base.getTitle()||base.Class.name)]; } if (repaint && (!this.getParent().isRendered)) { this.repaint('layout'); return false; } return repaint; end virtual method applyToolbarLayout(focusWidget, operation) var returnData = { repaint: false, skipParent: false }; var parent = focusWidget && focusWidget.getParent(); var toolbarAction = this.toolbarID && parent && this.toolbarID == parent.parentID; var applayToolbar = toolbarAction || (this.toolbarID && base.showToolbar && (!focusWidget || (operation == 'resize' && (focusWidget == this || this.needUpdateToolbar())) || (operation == 'insert' && focusWidget == this && this.needUpdateToolbar()))); if (applayToolbar) { returnData.repaint = this.getToolbar().layoutContents(focusWidget, operation); toolbarAction &= !returnData.repaint; } returnData.skipParent = toolbarAction; return returnData; end override virtual method layoutContents(focusWidget, operation) var rootInfo = this.buildRearrangeParams(focusWidget, operation); var changes = this.board.getChangesFromCache(rootInfo&&(rootInfo.focus||rootInfo.currentFocus)); RULE('rearrangeWidgets', base, this.board, rootInfo, changes); var repaint = !ISEMPTY(changes); if (repaint) { RULE('doApplyLayout', base, changes); if (!this.getParent().isRendered) this.repaint('layout'); } return repaint; end virtual method needUpdateToolbar() if (this.toolbarID && base.showToolbar) { var toolbands = base.toolbar.getToolbands(); var size = SPLIT(base.size); size = size && INT(size[0]) || 320; for (var iter in toolbands) { var toolband = toolbands[iter]; var _size = SPLIT(toolband.size); size -= (_size && INT(_size[0]) || 160); } if (size) return true; } return false; end override virtual method updateElements(operation, syncElems) if (this.toolbarID && base.showToolbar) this.getToolbar().updateElements(operation, syncElems); this.supercall(); if(typeof this.checkRows == 'function') this.checkRows(null, true); end <@doc scope="private"> Starts a shape rename operation virtual method startRename() var elem = this.base; if (elem.hasProperty('title')) return; // The title property is assumed to be [Custom] and we shouldn't get here anyways var diagram = this.getDiagram(); var board = diagram.board; var crec = $WIN.getBoardClientRect(); var cpos = board.offsetToAbsolute(this.elem, {x:1, y:1}); var scrollTop = board.editbox.scrollTop; var scrollLeft = board.editbox.scrollLeft; if (diagram.getWindow().base.isa('gml2:Popup')) { var offset = board.getOffset(); cpos.x += offset.offsetX; cpos.y += offset.offsetY + 18; // The board offset plus the model tabs height } var data = { object: elem, graphic: this, attr: 'name', callback: board.endRename, delegate: this, select: true, x: cpos.x + crec.x - scrollLeft, centerX:false, y: cpos.y + crec.y - scrollTop, centerY:false, w: 100, h: 8 }; board.textedit.show(data); end /* * Returns contents top gap. */ override virtual method getContentsTopGap() var titleHeight = this.ttlbar ? this.ttlbar.offsetHeight||0 : 0; var toolbarHeight = 0; var toolbar = this.getToolbar(); if (this.toolbarID && base.showToolbar) { // NOTE: DOM dependency var toolbarSize = SPLIT(toolbar.base.size); toolbarHeight = INT(toolbarSize[1])||toolbar.defaultHeight||0; } var selectorHeight = this.selector ? this.selector.offsetHeight||0 : 0; var height = 0; if (this.ttlbar && base.showTitlebar) height += titleHeight; if (this.toolbarID && toolbarHeight && toolbar.base.dock != 'bottom') height += toolbarHeight; if (this.selector) height += selectorHeight; return height; end /* * Returns contents left gap. */ override virtual method getContentsLeftGap() return this.selectionRow && !ISEMPTY(base.controls) ? (this.features.selectionRowSize||0) : 0; end virtual method hideCellSelection() if (!this.cellObject) return; var st = this.cellObject.style; st.visibility = 'hidden'; st.top = 0; st.left = 0; st.width = 1; st.height = 1; end override virtual method getArrowedWidgetFromPoint(point) var elems = []; var styles = []; var widget = this; var board = this.board; while(widget && !(widget.isa('core.lyt:PanelLayout') || ISA(widget.base, 'gml2:Layer'))) { var st = widget.elem.style; elems.push(st); styles.push(st.visibility); st.visibility = 'hidden'; var prev = widget; widget = board.getWidgetFromPoint(point); if (widget && widget.id == prev.id) break; } for (var len = elems.length, i = len - 1; i>= 0; i--) elems[i].visibility = styles[i]; return widget; end virtual method getFeaturesHeight() var titleHeight = this.ttlbar && base.showTitlebar ? (this.features.titleHeight||#[LYT_TTLBAR_HEIGHT]) : 0; var toolbarHeight = this.toolbarID && base.showToolbar ? INT(SPLIT(base.toolbar.size)[1]) : 0; var selectorHeight = this.selector ? (base.isa('gml2:Wizard') ? #[LYT_WIZARD_HEIGHT] : #[LYT_TABSTRIP_HEIGHT]) : 0; var pagbarHeight = this.pagbar && base.showPagingbar ? #[LYT_NAVBAR_HEIGHT] : 0; return titleHeight + toolbarHeight + selectorHeight + pagbarHeight; end virtual method getContentsOffsetHeight(baseSize) if (!baseSize) { var sessionCache = this.board.sessionCache; baseSize = SPLIT(sessionCache[base.id + '_size'] ? sessionCache[base.id + '_size'].value : base.size); } return MAX(baseSize[1] - this.getFeaturesHeight(), 0); end virtual method calcContentsW(w) return w; end virtual method calcContentsH(h) return h; end virtual method paintTableLines() var RULER_HGAP = 2; if (!this.main) this.main = this.createHtmlElement('DIV', null, null, this.contents); else this.main.innerHTML = ""; var map = base.grid.map; var table = this.createHtmlElement('TABLE', null, null, this.main); table.cellspacing = "0"; // define table cols: var c, cols; var colWidths = []; var lastRow = map.length - 1, useLastRow = false; for (c=0; ; ++c) { if (!map[0][c]) break; // calc column widths: var width = map[0][c].x2 - map[0][c].x1 - RULER_HGAP; colWidths.push(width); // detect if last row is required: if (map[lastRow][c].free == false) useLastRow = true; } var rows = lastRow; if (useLastRow) ++rows; if (colWidths.length == 1) { table.width = colWidths[0] + RULER_HGAP; } else { table.style.width = "100%"; } // create the rows / cells: for (var r=0; r 0 && map[r-1][c].ownerID == ctrlId) continue; else { var ctrl = base.controls[ctrlId]; if (ctrl.rowspan > 1) { rowspan = ctrl.rowspan; } } } var cell = this.createHtmlElement('TD', "TILE-CELL", null, row); // define the width, allow the last column to take the rest of the space: if (c < cols-1) cell.width = colWidths[c]; cell.innerHTML = " "; if (rowspan) cell.rowspan = rowspan; } } this.main.innerHTML = table.outerHTML; end