* The commands definition Map that will be automatically added and wired to the menubar and toolbar.\r
* See {@link org.argeo.ria.event.CommandsManager#definitions} for the keys to use for defining commands.\r
*/\r
- commands : {}\r
+ commands : {},\r
+ viewSelection : {\r
+ nullable:false, \r
+ check:"org.argeo.ria.components.ViewSelection"\r
+ },\r
+ instanceId : {init:""},\r
+ instanceLabel : {init:""}\r
},\r
\r
members : {\r
* @param viewPane {org.argeo.ria.components.ViewPane} The pane manager\r
* @return {Boolean}\r
*/\r
- init : function(viewPane){return true;},\r
+ init : function(viewPane, data){return true;},\r
/**\r
* The implementation should contain the real data loading (i.o. query...)\r
* @param data {mixed} Any data in any format\r
--- /dev/null
+qx.Class.define("org.argeo.ria.components.TabbedViewPane",\r
+{\r
+ extend : qx.ui.container.Composite,\r
+ implement : [org.argeo.ria.components.ILoadStatusable],\r
+\r
+ /**\r
+ * @param viewId {String} Unique id of this viewPane\r
+ * @param viewTitle {String} Readable Title of this viewPane\r
+ * @param splitPaneData {Map} Additionnal data to be used by splitpanes implementations.\r
+ */\r
+ construct : function(viewId, viewTitle){\r
+ this.base(arguments);\r
+ this.setViewId(viewId);\r
+ this._defaultViewTitle = viewTitle; \r
+ this.setLayout(new qx.ui.layout.Canvas());\r
+ this.blurredDecorator = new qx.ui.decoration.Uniform(1, "solid", "#000");\r
+ this.blurredDecorator.setBackgroundImage("decoration/app-header.png");\r
+ this.blurredDecorator.setBackgroundRepeat("scale");\r
+ this.setDecorator(this.blurredDecorator);\r
+\r
+ this.focusedDecorator = new qx.ui.decoration.Uniform(1, "solid", "#065fb2");\r
+ this.focusedDecorator.setBackgroundImage("decoration/app-header.png");\r
+ this.focusedDecorator.setBackgroundRepeat("scale");\r
+ \r
+ this.tabView = new qx.ui.tabview.TabView();\r
+ this.tabView.setAppearance("widget");\r
+ // Empty mode\r
+ this.add(this.tabView, {top: 7, width:"100%", bottom:0});\r
+ this.tabView.setBackgroundColor("#fff");\r
+ this.tabView.setMarginTop(27);\r
+ \r
+ this.tabView.addListener("changeSelected", function(){\r
+ this.fireEvent("changeSelection");\r
+ }, this);\r
+ \r
+ \r
+ this.setFocusable(true);\r
+ this.addListener("click", function(e){\r
+ this.fireDataEvent("changeFocus", this);\r
+ }, this); \r
+ \r
+ this.pageIds = {};\r
+ },\r
+\r
+ properties : {\r
+ /**\r
+ * Unique id of the pane\r
+ */\r
+ viewId : {init:""},\r
+ /**\r
+ * Human-readable title for this view\r
+ */\r
+ viewTitle : {init:"", event:"changeViewTitle"},\r
+ /**\r
+ * Has its own scrollable content \r
+ */\r
+ ownScrollable : {init: false, check:"Boolean"},\r
+ /**\r
+ * Map of commands definition\r
+ * @see org.argeo.ria.event.Command \r
+ */\r
+ commands : {init : null, nullable:true, check:"Map"}\r
+ \r
+ },\r
+ \r
+ members : {\r
+ contentExists : function(contentId){\r
+ if(this.pageIds[contentId]){\r
+ this.tabView.setSelected(this.pageIds[contentId]);\r
+ return this.pageIds[contentId].getUserData("argeoria.iview");\r
+ } \r
+ },\r
+ setContent : function(content){\r
+ if(!this.tabView.getChildren().length){\r
+ this.tabView.setBackgroundColor("transparent");\r
+ this.tabView.setMarginTop(0); \r
+ }\r
+ var contentId = content.getInstanceId();\r
+ var page = new qx.ui.tabview.Page(content.getInstanceLabel());\r
+ this.pageIds[contentId] = page;\r
+ page.setPadding(0);\r
+ page.setLayout(new qx.ui.layout.Canvas());\r
+ page.add(content, {width:"100%", top:0, bottom:0});\r
+ this.tabView.add(page); \r
+ page.setUserData("argeoria.iview", content); \r
+ content.getViewSelection().addListener("changeSelection", function(e){\r
+ this.fireEvent("changeSelection");\r
+ }, this);\r
+ this.tabView.setSelected(page);\r
+ },\r
+ getContent : function(){\r
+ if(this._getCrtPage()){\r
+ return this._getCrtPage().getUserData("argeoria.iview");\r
+ }\r
+ return null;\r
+ },\r
+ getViewSelection : function(){\r
+ if(!this.getContent()) return null;\r
+ return this.getContent().getViewSelection();\r
+ },\r
+ _getCrtPage : function(){\r
+ return this.tabView.getSelected();\r
+ },\r
+ closeCurrent : function(){\r
+ var crtPage = this._getCrtPage();\r
+ if(!crtPage) return;\r
+ var iView = crtPage.getUserData("argeoria.iview");\r
+ var iViewInstance = iView.getInstanceId();\r
+ iView.close(); \r
+ this.tabView.remove(crtPage);\r
+ delete(this.pageIds[iViewInstance]); \r
+ if(!this.tabView.getChildren().length){ // No more tabs : remove commands!\r
+ if(this.getCommands()){\r
+ org.argeo.ria.event.CommandsManager.getInstance().removeCommands(this.getCommands(), this.getViewId());\r
+ this.setCommands(null);\r
+ } \r
+ this.tabView.setBackgroundColor("#fff");\r
+ this.tabView.setMarginTop(27);\r
+ } \r
+ },\r
+ empty : function(){\r
+ var crtPage = this._getCrtPage();\r
+ while(crtPage){\r
+ this.closeCurrent();\r
+ crtPage = this._getCrtPage();\r
+ }\r
+ },\r
+ setOnLoad : function(load){\r
+ \r
+ },\r
+ focus : function(){\r
+ this.fireEvent("changeSelection");\r
+ this.setDecorator(this.focusedDecorator);\r
+ }, \r
+ blur : function(){\r
+ this.setDecorator(this.blurredDecorator);\r
+ }\r
+ }\r
+});
\ No newline at end of file
this.setViewId(viewId);
this._defaultViewTitle = viewTitle;
this.setViewTitle(viewTitle);
- var viewSelection = new org.argeo.ria.components.ViewSelection(viewId);
- this.setViewSelection(viewSelection);
if(splitPaneData){
this.setSplitPaneData(splitPaneData);
}
+ this.setFocusable(true);
+ this.addListener("click", function(e){
+ this.fireDataEvent("changeFocus", this);
+ }, this);
this.createGui();
},
+ events : {
+ "changeFocus" : "qx.event.type.Data",
+ "changeSelection" : "qx.event.type.Event"
+ },
+
properties :
{
/**
* Human-readable title for this view
*/
viewTitle : {init:"", event:"changeViewTitle"},
- /**
- * Selection model for this view
- */
- viewSelection : { nullable:false, check:"org.argeo.ria.components.ViewSelection" },
/**
* Has its own scrollable content
*/
*/
},
+ getViewSelection : function(){
+ if(this.getContent()){
+ return this.getContent().getViewSelection();
+ }
+ return null;
+ },
+
+ contentExists : function(iViewId){
+ return false;
+ },
+
/**
* Sets the content of this pane.
* @param content {org.argeo.ria.components.IView} An IView implementation
*/
- _applyContent : function(content){
+ _applyContent : function(content){
if(content == null) return;
var addScrollable = (content.addScroll?content.addScroll():false);
if(addScrollable){
this.guiContent = content;
this.add(this.guiContent, {flex:1});
}
+ content.getViewSelection().addListener("changeSelection", function(e){
+ this.fireEvent("changeSelection");
+ }, this);
},
/**
* Adds a graphical component too the header of the view pane.
}
this.setViewTitle(this._defaultViewTitle);
this.setContent(null);
+ },
+
+ focus : function(){
+ this.setDecorator(new qx.ui.decoration.Single(1,"solid","#065fb2"));
+ qx.event.Timer.once(function(){
+ this.fireEvent("changeSelection");
+ }, this, 200);
+ },
+ blur : function(){
+ this.setDecorator(new qx.ui.decoration.Single(1,"solid","#000"));
}
}
/**\r
* The main container for the org.argeo.ria.components.ViewPane instances. \r
*/\r
- viewPanesContainer : {init: null}\r
+ viewPanesContainer : {init: null},\r
+ currentFocus : {init :null}\r
},\r
construct : function(){\r
this.views = {};\r
* @param viewPaneId {String} The unique ID of the view pane\r
* @return {org.argeo.ria.components.IView}\r
*/\r
- initIViewClass: function(classObj, viewPaneId){\r
+ initIViewClass: function(classObj, viewPaneId, data){\r
+ var viewPane = this.getViewPaneById(viewPaneId); \r
var iView = new classObj;\r
- var viewPane = this.getViewPaneById(viewPaneId);\r
- iView.init(viewPane); \r
+ iView.init(viewPane, data);\r
+ var existingView = viewPane.contentExists(iView.getInstanceId()); \r
+ if(existingView){\r
+ delete iView;\r
+ return existingView;\r
+ }\r
var commands = iView.getCommands();\r
- viewPane.empty();\r
+ //viewPane.empty();\r
if(commands){\r
viewPane.setCommands(commands);\r
- org.argeo.ria.event.CommandsManager.getInstance().addCommands(commands, "view:"+viewPaneId);\r
+ org.argeo.ria.event.CommandsManager.getInstance().addCommands(commands, "view:"+viewPaneId, viewPaneId);\r
}\r
viewPane.setContent(iView); \r
return iView;\r
*/\r
registerViewPane : function(viewPane){\r
this.views[viewPane.getViewId()] = viewPane;\r
- viewPane.getViewSelection().addListener("changeSelection", function(e){\r
- org.argeo.ria.event.CommandsManager.getInstance().refreshCommands(e.getData());\r
- }); \r
+ viewPane.addListener("changeSelection", function(e){\r
+ var viewSelection = e.getTarget().getViewSelection();\r
+ if(!viewSelection) return;\r
+ org.argeo.ria.event.CommandsManager.getInstance().refreshCommands(viewSelection);\r
+ });\r
+ viewPane.addListener("changeFocus", function(e){\r
+ for(var key in this.views){\r
+ this.views[key].blur();\r
+ }\r
+ viewPane.focus();\r
+ this.setCurrentFocus(viewPane);\r
+ }, this);\r
},\r
/**\r
* Returns a viewPane by its unique id.\r
this.setLabel(label);\r
this.setIcon(icon); \r
this.menuClones = [];\r
+ this.callbacks = {};\r
},\r
\r
members :\r
this.addTooltip(button);\r
return button;\r
},\r
- \r
+ \r
+ registerCallback : function(callback, focusablePartId){\r
+ this.callbacks[focusablePartId] = callback;\r
+ },\r
+ getCallbacks : function(){\r
+ return this.callbacks;\r
+ },\r
+ removeCallback : function(focusablePartId){\r
+ if(this.callbacks[focusablePartId]){\r
+ delete this.callbacks[focusablePartId];\r
+ }\r
+ }, \r
+ \r
/**\r
* Special tricks using UserData to enable/disable listeners to avoid loops...\r
* @param button {qx.ui.core.Widget} toolbar Checkbox or menu Checkbox button.\r
initialDefinitions : {\r
init : {},\r
check : "Map"\r
+ },\r
+ sharedDefinitions : {\r
+ init: {},\r
+ check: "Map"\r
}\r
},\r
\r
this.menus = {};\r
this.toolbars = {};\r
var defs = this.getDefinitions();\r
+ var shared = this.getSharedDefinitions();\r
for(var key in defs){\r
var definition = defs[key];\r
var command;\r
definition.command = command;\r
}else{\r
command = definition.command;\r
+ if(shared[key]){\r
+ \r
+ for(var focusPartId in shared[key]){\r
+ var sharedCommand = shared[key][focusPartId];\r
+ if(sharedCommand.callback){\r
+ var split = sharedCommand.callbackContext.split(":");\r
+ var focusPart = split[0];\r
+ var viewId = split[1]; \r
+ command.registerCallback(sharedCommand.callback, split[1]); \r
+ //this._attachListener(command, sharedCommand.callback, sharedCommand.callbackContext);\r
+ } \r
+ }\r
+ \r
+ }\r
}\r
if(definition.menu){\r
if(!this.menus[definition.menu]) this.menus[definition.menu] = [];\r
*/\r
refreshCommands : function(viewSelection){\r
var defs = this.getDefinitions();\r
+ var shared = this.getSharedDefinitions();\r
var xmlNodes = null;\r
if(viewSelection.getCount() > 0){\r
var xmlNodes = viewSelection.getNodes();\r
for(var key in defs){\r
var definition = defs[key];\r
if(!definition.selectionChange) continue;\r
+ if(shared[key]){\r
+ var currentFocus = org.argeo.ria.components.ViewsManager.getInstance().getCurrentFocus();\r
+ if(!currentFocus) continue;\r
+ var sharedComm = shared[key][currentFocus.getViewId()];\r
+ if(sharedComm && sharedComm.selectionChange){\r
+ var binded = qx.lang.Function.bind(sharedComm.selectionChange, definition.command);\r
+ binded(viewSelection.getViewId(), xmlNodes);\r
+ }\r
+ }\r
var binded = qx.lang.Function.bind(definition.selectionChange, definition.command);\r
binded(viewSelection.getViewId(), xmlNodes);\r
}\r
* @param definitions {Map} a set of commands definitions.\r
* @param callbackContext {qx.ui.core.Object} The context used inside the commands callbacks. \r
*/\r
- addCommands : function(definitions, callbackContext){\r
+ addCommands : function(definitions, callbackContext, focusablePartId){\r
var crtDefs = this.getDefinitions(); \r
for(var key in definitions){\r
if(callbackContext) definitions[key]['callbackContext'] = callbackContext;\r
- crtDefs[key] = definitions[key];\r
+ if(crtDefs[key] && definitions[key]['shared']){\r
+ if(focusablePartId) {\r
+ definitions[key]['focusablePartId'] = focusablePartId;\r
+ if(!this.getSharedDefinitions()[key]){\r
+ this.getSharedDefinitions()[key] = {};\r
+ }\r
+ this.getSharedDefinitions()[key][focusablePartId] = definitions[key];\r
+ }\r
+ \r
+ }else{\r
+ crtDefs[key] = definitions[key];\r
+ }\r
}\r
this.setDefinitions(crtDefs);\r
this.fireEvent("changedCommands");\r
* Removes a whole set of commands by their definitions maps.\r
* @param definitions {Map} a set of commands definitions\r
*/\r
- removeCommands : function(definitions){\r
+ removeCommands : function(definitions, focusablePartId){\r
var crtDefs = this.getDefinitions();\r
var initDefs = this.getInitialDefinitions();\r
+ var sharedDefs = this.getSharedDefinitions();\r
for(var key in definitions){\r
if(!crtDefs[key]) continue;\r
if(initDefs[key]){\r
crtDefs[key] = initDefs[key];\r
}else{\r
- delete crtDefs[key];\r
+ if(sharedDefs[key] && sharedDefs[key][focusablePartId]){\r
+ crtDefs[key].command.removeCallback(focusablePartId);\r
+ delete sharedDefs[key][focusablePartId];\r
+ }else{\r
+ delete crtDefs[key];\r
+ }\r
}\r
}\r
this.setDefinitions(crtDefs);\r
return;\r
} \r
if(typeof(callbackContext) == "string"){\r
+ \r
+ var split = callbackContext.split(":");\r
+ var focusPart = split[0];\r
+ var viewId = split[1];\r
+ if(command.getCallbacks()[viewId]) return;\r
+ command.registerCallback(callback, split[1]);\r
+ command.addListener("execute", function(event){\r
+ var target = event.getTarget();\r
+ var callbacks = target.getCallbacks();\r
+ if(qx.lang.Object.getLength(callbacks) == 0) return;\r
+ var view = org.argeo.ria.components.ViewsManager.getInstance().getViewPaneById(viewId).getContent();\r
+ if(qx.lang.Object.getLength(callbacks) == 1){\r
+ var binded = qx.lang.Function.bind(callbacks[qx.lang.Object.getKeys(callbacks)[0]], view);\r
+ binded(event);\r
+ return;\r
+ }\r
+ var currentFocus = org.argeo.ria.components.ViewsManager.getInstance().getCurrentFocus();\r
+ if(currentFocus && currentFocus.getViewId() && callbacks[currentFocus.getViewId()]){\r
+ var binded = qx.lang.Function.bind(callbacks[currentFocus.getViewId()], view);\r
+ binded(event);\r
+ return;\r
+ }\r
+ });\r
+ \r
+ \r
+ /*\r
if(callbackContext.split(":")[0] == "view"){\r
var viewId = callbackContext.split(":")[1];\r
command.addListener("execute", function(event){\r
+ if(event.getTarget().getCheckFocusAtCallback()){\r
+ var currentFocus = org.argeo.ria.components.ViewsManager.getInstance().getCurrentFocus();\r
+ if(currentFocus.getViewId() != viewId) return;\r
+ }\r
var view = org.argeo.ria.components.ViewsManager.getInstance().getViewPaneById(viewId).getContent();\r
var binded = qx.lang.Function.bind(callback, view);\r
binded(event);\r
}else{\r
command.addListener("execute", callback, callbackContext);\r
}\r
+ */\r
}\r
}\r
}\r