Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Using a dragTarget on a CSS Button

    Hi,

    I'm trying to use the dragTarget property on a CSS driven Button onto which I've added a children Img
    component to be used as a drag handle. I use 'parent' as the value for the dragTarget property.

    The problem is that the drag "hot spot" is not overlaid at the right place on the underlying button.

    I can only drag if I grip the extreme right portion (almost outside) of the parent component, instead
    of gripping the area the children Img component is covering.

    Here's the code to reproduce:

    Code:
    var btn = IButton.create
    ({
    	layoutAlign : 'center',
    	height : 30,
    	width : '100%',
    	showRollOver : false,
    	showDown : false,
    	canFocus : true,
    	showFocus : true,
    	dragHandleWidth : 19,
    	dragHandleHeight : 16,
    	title : 'My button',
    	click : 'alert(123)',
    	children :
    	[
    		Img.create
    		({
    			src : 'dragHandle.png',
    			imageType : 'normal',
    			width : this.dragHandleWidth,
    			imageWidth : this.dragHandleWidth,
    			height : this.dragHandleHeight,
    			imageHeight : this.dragHandleHeight,
    			canFocus : true,
    			canHover : true,
    			canDrag : true,
    			canDrop : true,
    			canDragReposition : true,
    			dragTarget : 'parent',
    			dragAppearance : 'target'
    		})
    	],
    	resized : function (deltaX, deltaY)
    	{
    		this.Super('resized', arguments);
    
    		if (this.children && this.children.length > 0)
    		{
    			this.children[0].setLeft(this.getInnerWidth() - this.dragHandleWidth - 4);
    			this.children[0].setTop((this.getInnerHeight() - this.dragHandleHeight) / 2);
    		}
    	}
    });
    We're getting this behavior using ISC version 8 nightly from 07/07, both under FF 3.6.6 (Mac) and IE 8 (Win).

    Any idea how can I get this to work?

    Thanking you again for your assistance.

    Kind regards,

    #2
    It looks as if the Label was overlaid over the custom Img drag handle/grip.
    Could this be a click mask issue ? How can we make this work ?

    Thanks in advance for your help!

    Comment


      #3
      Try calling bringToFront on the Img after the Button is drawn.

      Comment


        #4
        Unfortunately, I had already tried that and it doesn't work ... FYI, using the ISC dev console, I've gathered the following:

        isc_IButton_8.zIndex = 201620
        isc_Img_8.zIndex = 800558
        isc_IButton_8_Label.zIndex = 201621

        This confirms that the z-order of the Img is higher than both the actual underlying parent button as well as its associated label.

        The only way I'm getting closer to something (although still not fully working), is creating the dragHandle Img separately and
        using btn.label.addPeer(dragHandle) following the creation of the button.

        Thanks,

        Comment


          #5
          Here's the latest/alternative implementation I'm using which yields almost good results ...

          Code:
          // create button
          
          var btn = IButton.create
          ({
          	layoutAlign : 'center',
          	height : 30,
          	width : '100%',
          	showRollOver : false,
          	showDown : false,
          	canFocus : true,
          	showFocus : true,
          	dragHandleWidth : 19,
          	dragHandleHeight : 16,
          	dragHandle : null,
          	canDrop : true,
          	title : 'My button',
          	click : 'alert(123)',
          	resized : function (deltaX, deltaY)
          	{
          		this.Super('resized', arguments);
          
          		if (this.dragHandle)
          		{
          			// adjust drag handle/grip y coordinate and height
          
          			this.dragHandle.setLeft(this.getWidth() - this.dragHandleWidth - 4);
          			this.dragHandle.setWidth(this.dragHandleWidth);
          			this.dragHandle.setTop((this.getHeight() - this.dragHandleHeight) / 2);
          			this.dragHandle.setHeight(this.dragHandleHeight);
          		}
          
          		this.ensureDragHandleVisible();
          	},
          	ensureDragHandleVisible : function()
          	{
          		if (this.dragHandle)
          			this.dragHandle.bringToFront();
          	}
          });
          
          // create drag handle/grip
          
          btn.dragHandle = Img.create
          ({
          	src : 'dragHandle.png',
          	imageType : 'normal',
          	width : btn.dragHandleWidth,
          	imageWidth : btn.dragHandleWidth,
          	height : btn.dragHandleHeight,
          	imageHeight : btn.dragHandleHeight,
          	canFocus : true,
          	canHover : true,
          	canDrag : true,
          	canDrop : true,
          	canDragReposition : true,
          	dragTarget : btn,
          	dragAppearance : 'target',
          	click : function() {}
          });
          
          // attach drag handle/grip onto button label
          
          btn.label.addPeer(btn.dragHandle);
          The problems I'm still having with this approach are the following:

          1) The Img (dragHandle) gets created with a size of 100x100 although I've specified a specific/smaller size.

          2) When I start dragging (before dropping), the dragHandle gets removed from the button on which its sitting (looks weird).

          3) When a resize event occurs, all dragHandle Img components get moved to the top of the Layout which hosts the outter IButton.

          Thanks again for your help.

          Kind regards,
          Last edited by yavery; 16 Jul 2010, 09:59.

          Comment


            #6
            The original code is closer to the correct approach. Given that code, the problems were:

            1. you are trying to delegate a drag to a dragTarget that is not draggable. Need to set canDrag:true on the Button as a whole

            2. wrong scope for "this.dragHandleWidth" et al - in that scope "this" referred to the Window

            Corrected code below.

            Code:
            var btn = isc.IButton.create
            ({
                autoDraw:true,
            	layoutAlign : 'center',
            	height : 30,
            	width : '100%',
            	showRollOver : false,
            	showDown : false,
            	canFocus : true,
            	showFocus : true,
                canDrag:true,
            	dragHandleWidth : 19,
            	dragHandleHeight : 16,
            	title : 'My button',
            	click : 'alert(123)',
            	children :
            	[
            		isc.Img.create
            		({
            			src : "[SKINIMG]actions/remove.png",
            			imageType : 'normal',
            			width : 16,
            			imageWidth : 16,
            			height : 16, 
            			imageHeight : 16,
            			//canFocus : true,
            			//canHover : true,
            			canDrag : true,
            			//canDrop : true,
            			canDragReposition : true,
            			dragTarget : 'parent',
            			dragAppearance : 'target'
            		})
            	],
            	resized : function (deltaX, deltaY)
            	{
            		this.Super('resized', arguments);
            
            		if (this.children && this.children.length > 0)
            		{
            			this.children[0].setLeft(this.getInnerWidth() - this.dragHandleWidth - 4);
            			this.children[0].setTop((this.getInnerHeight() - this.dragHandleHeight) / 2);
            		}
            	}
            }).children[0].bringToFront();

            Comment


              #7
              Thanks,

              The provided code works, but the initial intent was to have only the dragHandle allow dragging
              of the button, not the entire button itself.

              Drag handle to drag and rest of button for clicking (no dragging).

              We'd like the mouse cursor to show DRAG status only when hovering over the dragHandle and
              have the mouse cursor show CLICK status when hovering the rest of the button area ...

              Is that possible, because the current code doesn't seem to be doing that ?

              Thanks,

              Comment


                #8
                Ah, OK, this is not actually what we call a CSS button (isc.Button) as you first stated, and for non-CSS buttons, which are based on isc.StretchImgButton, there is actually a separate auto-generated Label component which floats over the button. Because of this, relative zIndex between the Img and Label don't matter - they have different parents.

                The simplest way to achieve this interaction is to have both the Button and dragHandle as children of a third "container" component. Then bringToFront() really will place the dragHandle above the button & it's label, since all have the same parent.

                If you don't want the additional container component, you can continue with your current approach, but don't make the dragHandle a peer. Peers have a lot of automatic behavior most of which you don't want, including resizing to match the master. Just have the button move the dragHandle with it via an override or observation of button.moved().

                Comment


                  #9
                  Thanks for the suggestion. It works using that approach.

                  Following is the code, if anyone else wants to do something similar.

                  Code:
                  var dragHandleWidth = 21;
                  var dragHandleHeight = 18;
                  
                  var layout = Canvas.create
                  ({
                  	autoDraw : true,
                  	membersSpacing : 5,
                  	height : 30,
                  	width : '100%',
                  	btn : null,
                  	dragHandle : null,
                  	canDrop : true,
                  	children :
                  	[
                  		IButton.create
                  		({
                  			autoDraw : true,
                  			thisLayout : this,
                  			layoutAlign : 'center',
                  			height : 30,
                  			width : '100%',
                  			showRollOver : true,
                  			showDown : true,
                  			canFocus : true,
                  			showFocus : true,
                  			title : 'My button',
                  			click : 'alert(123)'
                  		}),
                  		Img.create
                  		({
                  			autoDraw : true,
                  			src : "dragHandle.png",
                  			imageType : 'normal',
                  			width : dragHandleWidth,
                  			imageWidth : dragHandleWidth,
                  			height : dragHandleHeight, 
                  			imageHeight : dragHandleHeight,
                  			canDrag : true,
                  			canDragReposition : true,
                  			dragTarget : 'parent',
                  			dragAppearance : 'target',
                  			click : function() {}
                  		})
                  	],
                  	initWidget : function()
                  	{
                  		this.Super('initWidget', arguments);
                  
                  		this.btn = this.children[0];
                  		this.dragHandle = this.children[1];
                  
                  		this.observe(this.btn, 'resized', 'observer.dragHandleAdjust()');
                  		this.observe(this.btn, 'moved', 'observer.dragHandleAdjust()');
                  	},
                  	dragHandleAdjust : function()
                  	{
                  		if (this.dragHandle)
                  		{
                  			this.dragHandle.bringToFront();
                  
                  			this.dragHandle.setLeft(this.btn.getInnerWidth() - dragHandleWidth - 4);
                  			this.dragHandle.setTop((this.btn.getInnerHeight() - dragHandleHeight) / 2);
                  		}
                  	}
                  });
                  Regards,

                  Comment

                  Working...
                  X