]> git.argeo.org Git - gpl/argeo-slc.git/commitdiff
Changed architecture to enable TabViewPane and sharing actions in the toolbar, depend...
authorCharles du Jeu <charles.dujeu@gmail.com>
Sun, 25 Jan 2009 17:39:24 +0000 (17:39 +0000)
committerCharles du Jeu <charles.dujeu@gmail.com>
Sun, 25 Jan 2009 17:39:24 +0000 (17:39 +0000)
git-svn-id: https://svn.argeo.org/slc/trunk@2127 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

org.argeo.slc.webapp/src/main/webapp/argeo-ria-src/class/org/argeo/ria/components/IView.js
org.argeo.slc.webapp/src/main/webapp/argeo-ria-src/class/org/argeo/ria/components/TabbedViewPane.js [new file with mode: 0644]
org.argeo.slc.webapp/src/main/webapp/argeo-ria-src/class/org/argeo/ria/components/ViewPane.js
org.argeo.slc.webapp/src/main/webapp/argeo-ria-src/class/org/argeo/ria/components/ViewsManager.js
org.argeo.slc.webapp/src/main/webapp/argeo-ria-src/class/org/argeo/ria/event/Command.js
org.argeo.slc.webapp/src/main/webapp/argeo-ria-src/class/org/argeo/ria/event/CommandsManager.js

index 9968aa8434ef96069537e71d6ea86ccc64fac62f..6fe9bcbbb803e494ca09d3db2bed43bfb4c8b534 100644 (file)
@@ -18,7 +18,13 @@ qx.Interface.define("org.argeo.ria.components.IView", {
                 * 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
@@ -29,7 +35,7 @@ qx.Interface.define("org.argeo.ria.components.IView", {
                 * @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
diff --git a/org.argeo.slc.webapp/src/main/webapp/argeo-ria-src/class/org/argeo/ria/components/TabbedViewPane.js b/org.argeo.slc.webapp/src/main/webapp/argeo-ria-src/class/org/argeo/ria/components/TabbedViewPane.js
new file mode 100644 (file)
index 0000000..c5ed23a
--- /dev/null
@@ -0,0 +1,139 @@
+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
index a82420b202a805ea03b04879573cac0b28607576..bc7c8daa0a82e8cb455a2edabbe06e3678660b9f 100644 (file)
@@ -19,14 +19,21 @@ qx.Class.define("org.argeo.ria.components.ViewPane",
        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 : 
   {
        /**
@@ -37,10 +44,6 @@ qx.Class.define("org.argeo.ria.components.ViewPane",
         * 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 
         */
@@ -127,11 +130,22 @@ qx.Class.define("org.argeo.ria.components.ViewPane",
                */
        },
        
+       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){
@@ -142,6 +156,9 @@ qx.Class.define("org.argeo.ria.components.ViewPane",
                        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.
@@ -187,6 +204,16 @@ qx.Class.define("org.argeo.ria.components.ViewPane",
                }
                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"));
        }
 
   }
index 689e61b356f8ee9460fbb71d933a34521498e21c..56420d3b952afef236fc0d0feabf8f8f1949392c 100644 (file)
@@ -18,7 +18,8 @@ qx.Class.define("org.argeo.ria.components.ViewsManager",
        /**\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
@@ -32,15 +33,20 @@ qx.Class.define("org.argeo.ria.components.ViewsManager",
         * @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
@@ -52,9 +58,18 @@ qx.Class.define("org.argeo.ria.components.ViewsManager",
         */\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
index 36c18fc37e139453ea17e1c75c0ecb05b636d1e1..9ad87c5b9a926e5d8505c7c69a17b74b5b659eef 100644 (file)
@@ -54,6 +54,7 @@
        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
index 573c11ff642fe80da8643aba2bf25336ab8689a6..6452a3a87f313761fed6a9bf8670ef52ff2b5f6e 100644 (file)
@@ -83,6 +83,10 @@ qx.Class.define("org.argeo.ria.event.CommandsManager",
        initialDefinitions : {\r
                init : {},\r
                check : "Map"\r
+       },\r
+       sharedDefinitions : {\r
+               init: {},\r
+               check: "Map"\r
        }\r
   },\r
 \r
@@ -113,6 +117,7 @@ qx.Class.define("org.argeo.ria.event.CommandsManager",
                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
@@ -137,6 +142,20 @@ qx.Class.define("org.argeo.ria.event.CommandsManager",
                                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
@@ -156,6 +175,7 @@ qx.Class.define("org.argeo.ria.event.CommandsManager",
         */\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
@@ -163,6 +183,15 @@ qx.Class.define("org.argeo.ria.event.CommandsManager",
                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
@@ -256,11 +285,22 @@ qx.Class.define("org.argeo.ria.event.CommandsManager",
         * @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
@@ -269,15 +309,21 @@ qx.Class.define("org.argeo.ria.event.CommandsManager",
         * 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
@@ -345,9 +391,39 @@ qx.Class.define("org.argeo.ria.event.CommandsManager",
                        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
@@ -355,6 +431,7 @@ qx.Class.define("org.argeo.ria.event.CommandsManager",
                        }else{\r
                                command.addListener("execute", callback, callbackContext);\r
                        }\r
+                       */\r
                }\r
        }\r
   }\r