@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