-
3 Mar 2010 11:57 AM #11
From what I'm finding, this.ownerCt.isVisible() returns true even when it really isnt.
I'm confused because the ghostbar is a plugin to a panel which is inside a tab panel.
When either the panel shades OR the current tab is changed on the tabpanel, the ghostbar still renders but realigns to (0,0) placing it in the upper left.
I'm not sure why it realigns up there though. It's almost like this.ownerCt is returning the parent of the parent which would be the tab panel, which is visible and thus the toolbar gets drawn.
-
3 Mar 2010 12:05 PM #12
The ownerCt Panel may be visible, but ITS ownerCt may be hidden. There will have to be a "recursive" parameter to Component.isVisible which goes all the way up the chain.
I'll leave that as an exercise for you.Search the forum: http://www.google.com/coop/cse?cx=01...%3Az7of1ufqccu
Read the docs too: http://extjs.com/deploy/dev/docs/
Scope: http://extjs.com/forum/showthread.ph...642#post257642
-
3 Mar 2010 1:12 PM #13
In my case I *always* use the plugin inside a shadeable panel.
My hack was to simply check twice and never any higher. Also added a hide for when it fails the test yet it's visible.
The other thought was to also check the parent component for the "beforeCollapse" event, and if it exists, listen to it and hide() on invocation.
My updated code is here for anyone else solving these problems.
Code:checkMousePosition: function(e) { this.syncPosition(); var o = 1, d = this.region.getDistanceBetween(e.getPoint()); if (d > this.threshold + this.fullVisibilityZone) { this.hide(); } else if ((d -= this.fullVisibilityZone) > 0) { // Mouse is within range of this Toolbar, so show it if its not already visible if (!this.isVisible()) { if (this.ownerCt.isVisible() && this.ownerCt.ownerCt.isVisible()) { this.show(); } } else { if (!this.ownerCt.isVisible() || !this.ownerCt.ownerCt.isVisible()) { this.hide(); } } o = 1 - (d / this.threshold); } this.el.setStyle({ opacity: o, //'z-index': this.ownerCt.el.zindex+3 'z-index': 20 }); },
-
3 Mar 2010 1:18 PM #14
How about an override of Component.isVisible?
Search the forum: http://www.google.com/coop/cse?cx=01...%3Az7of1ufqccu
Read the docs too: http://extjs.com/deploy/dev/docs/
Scope: http://extjs.com/forum/showthread.ph...642#post257642
-
3 Mar 2010 2:04 PM #15
-
3 Mar 2010 2:35 PM #16
You're going to have to do it sooner or later. It's not as if there isn't deep and complete documentation, and hundreds of examples.
Search the forum: http://www.google.com/coop/cse?cx=01...%3Az7of1ufqccu
Read the docs too: http://extjs.com/deploy/dev/docs/
Scope: http://extjs.com/forum/showthread.ph...642#post257642
-
8 Apr 2010 12:41 PM #17
I solved this by adding a new function to the GhostBar superclass called "parentsVisible" which simply accepts a start object and traverses it back up until there is no parent. It checks each step for a non visible parent and short circuits as soon as one isn't.
There is one caveat I should mention and that's when the passed object doesnt have a parent. That will return true and that's simply by design since the function doesnt care if the passed object is visible or not, only it's parents. And if it has none, then technically all the parent's are visible.
Code:parentsVisible: function(start) { var current = start; //alert(start); while(current) { if (current.ownerCt) { if (current.ownerCt.isVisible()) { current = current.ownerCt; } else { return false; } } else { return true; } } return false; }, checkMousePosition: function(e) { this.syncPosition(); var o = 1, d = this.region.getDistanceBetween(e.getPoint()); if (d > this.threshold + this.fullVisibilityZone) { this.hide(); } else if ((d -= this.fullVisibilityZone) > 0) { // Mouse is within range of this Toolbar, so show it if its not already visible if (!this.isVisible()) { if (this.parentsVisible(this)) { this.show(); } } else { if (!this.parentsVisible(this)) { this.hide(); } } o = 1 - (d / this.threshold); } this.el.setStyle({ opacity: o, //'z-index': this.ownerCt.el.zindex+3 'z-index': 20 }); },
-
9 Apr 2010 11:30 AM #18
I also found that my new function didn't properly handle collapsed panels, so i added a quick check for that. Updated code below.
Code:parentsVisible: function(start) { var current = start; //alert(start); while(current) { if (current.ownerCt) { if (current.ownerCt.isVisible()) { if (current.ownerCt.collapsed) { return false; } current = current.ownerCt; } else { return false; } } else { return true; } } return false; }, checkMousePosition: function(e) { this.syncPosition(); var o = 1, d = this.region.getDistanceBetween(e.getPoint()); if (d > this.threshold + this.fullVisibilityZone) { this.hide(); } else if ((d -= this.fullVisibilityZone) > 0) { // Mouse is within range of this Toolbar, so show it if its not already visible if (!this.isVisible()) { if (this.parentsVisible(this)) { this.show(); } } else { if (!this.parentsVisible(this)) { this.hide(); } } o = 1 - (d / this.threshold); } this.el.setStyle({ opacity: o, //'z-index': this.ownerCt.el.zindex+3 'z-index': 20 }); },
-
18 May 2010 12:04 PM #19
Posted full version here since someone on IRC asked and said it wasn't obvious which code snippit to use.
This one has my additional function for handling visibility.
Code:Ext.override(Ext.lib.Region, { /** * Returns the shortest distance between this Region and another Region. * Either or both Regions may be Points. * @param {Region} r The other Region * @return {Number} The shortest distance in pixels between the two Regions. */ getDistanceBetween: function(r) { // We may need to mutate r, so make a copy. r = Ext.apply({}, r); // Translate r to the left of this if (r.left > this.right) { var rWidth = r.right - r.left; r.left = this.left - (r.left - this.right) - rWidth; r.right = r.left + rWidth; } // Translate r above this if (r.top > this.bottom) { var rHeight = r.bottom - r.top; r.top = this.top - (r.top - this.bottom) - rHeight; r.bottom = r.top + rHeight; } // If r is directly above if (r.right > this.left) { return this.top - r.bottom; } // If r is directly to the left if (r.bottom > this.top) { return this.left - r.right; } // r is on a diagonal path return Math.round(Math.sqrt(Math.pow(this.top - r.bottom, 2) + Math.pow(this.left - r.right, 2))); } }); /** * @class Ext.ux.GhostBar * @extends Ext.Toolbar * A Toolbar class which attaches as a plugin to any BoxComponent, and fades in at the configured * position whenever the mouse is brought within a configurable threshold. eg: <code><pre> new Ext.Panel({ renderTo: document.body, title: 'Test', width: 600, height: 400, plugins: [ new Ext.ux.GhostBar([{ text: 'Click Me' }]) ] }); </pre></code> */ Ext.ux.GhostBar = Ext.extend(Ext.Toolbar, { listenerAdded: false, cache: [], /** * @cfg {Number} threshold The number of pixels around the toolbar position in which * opacity is 100%. */ fullVisibilityZone: 50, /** * @cfg {Number} threshold The number of pixels around the full visibility zone in which * fading is performed. */ threshold: 100, /** * @cfg {String} position The alignment of this Toolbar, <code><b>top</b></code>, or <code><b>bottom</b></code>. * Defaults to <code><b>bottom</b></code>. */ /** * @cfg {Array} offsets A two element Array containing the [x, y] offset from the default position * in which to display the Toolbar. */ initComponent: function() { // Only use one mousemove listener. Check the cache of GhostBars for proximity on each firing if (!this.listenerAdded) { Ext.getDoc().on('mousemove', Ext.ux.GhostBar.prototype.onDocMouseMove, Ext.ux.GhostBar.prototype); this.listenerAdded = true; } this.renderTo = document.body; this.hideMode = 'visibility'; Ext.ux.GhostBar.superclass.initComponent.apply(this, arguments); }, onRender: function() { Ext.ux.GhostBar.superclass.onRender.apply(this, arguments); this.el.setStyle({ position: 'absolute' }); this.hide(); this.cache.push(this); }, init: function(c) { this.ownerCt = c; c.on({ render: this.onClientRender, scope: this, single: true }); c.onPosition = c.onPosition.createSequence(this.onClientPosition, this); c.onResize = c.onResize.createSequence(this.onClientResize, this); }, onClientRender: function() { this.clientEl = this.ownerCt.getLayoutTarget ? this.ownerCt.getLayoutTarget() : this.ownerCt.el; }, onClientResize: function() { this.setWidth(this.clientEl.getWidth(true)); this.syncPosition(); }, onClientPosition: function() { this.syncPosition(); }, syncPosition: function() { var offsets = [this.clientEl.getBorderWidth('l'), 0]; if (this.offsets) { offsets[0] += this.offsets[0]; offsets[1] += this.offsets[1]; } this.el.alignTo(this.clientEl, (this.position == 'top') ? 'tl-tl' : 'bl-bl', offsets); this.region = this.el.getRegion(); }, onDocMouseMove: function(e) { for (var i = 0; i < this.cache.length; i++) { if (this.cache[i].ownerCt.isVisible()) { this.checkMousePosition.call(this.cache[i], e); } } }, checkMousePosition: function(e) { this.syncPosition(); var o = 1, d = this.region.getDistanceBetween(e.getPoint()); if (d > this.threshold + this.fullVisibilityZone) { this.hide(); } else if ((d -= this.fullVisibilityZone) > 0) { // Mouse is within range of this Toolbar, so show it if its not already visible if (!this.isVisible()) { this.show(); } o = 1 - (d / this.threshold); } this.el.setStyle({ opacity: o, 'z-index': this.ownerCt.el.zindex+3 }); }, onDestroy: function() { // Uncache this Toolbar when we are destroyed this.cache.splice(this.cache.indexOf(this), 1); Ext.ux.GhostBar.superclass.onDestroy.apply(this, arguments); }, parentsVisible: function(start) { var current = start; //alert(start); while(current) { if (current.ownerCt) { if (current.ownerCt.isVisible()) { if (current.ownerCt.collapsed) { return false; } current = current.ownerCt; } else { return false; } } else { return true; } } return false; }, checkMousePosition: function(e) { this.syncPosition(); var o = 1, d = this.region.getDistanceBetween(e.getPoint()); if (d > this.threshold + this.fullVisibilityZone) { this.hide(); } else if ((d -= this.fullVisibilityZone) > 0) { // Mouse is within range of this Toolbar, so show it if its not already visible if (!this.isVisible()) { if (this.parentsVisible(this)) { this.show(); } } else { if (!this.parentsVisible(this)) { this.hide(); } } o = 1 - (d / this.threshold); } this.el.setStyle({ opacity: o, //'z-index': this.ownerCt.el.zindex+3 'z-index': 20 }); }, });
-
20 May 2010 3:18 PM #20
Hello, i'm using this plugin... it very good. But i have a problem... if the panel where i use this plugin have a scrollbar, the GhostBar is over the scrollbar... it's possible to solve this.
Thanks in advance,Portugal
Castelo Branco


Reply With Quote
