1. #1
    Sencha User
    Join Date
    Mar 2012
    Posts
    12
    Vote Rating
    0
    Lionlancer is on a distinguished road

      0  

    Default Unanswered: Wrong alignment of Panels inside HBox and VBox

    Unanswered: Wrong alignment of Panels inside HBox and VBox


    Hello everyone!

    I made a combination of HBox and VBox (where VBox is a child of HBox) and I added a drag and drop feature. I did it this way because I want to make it similar to a windows way of rearranging and resizing panels (and since using Border Layout is not adviced for moving/removing panels). I encountered a bug while doing this. Try rearranging the panels (by dragging) vertically to see what I mean (for example: try moving "hbp2-vboxpanel1" and "hbp2-vboxpanel2" on top/bottom of "hbp1-vboxpanel1").

    I've been working on it for weeks and made a lot of research and experimentation to make it work right. There are still a few bugs I need to fix but the one I really want to be fixed is the alignment of panels after doLayout() which is called automatically (which happens after you drop the panel).

    Attached are the codes:

    index.html
    HTML Code:
    <html>
    <head>
        <title>Hello Ext</title>
     
        <link rel="stylesheet" type="text/css" href="extjs/resources/css/ext-all.css">
        <link rel="stylesheet" type="text/css" href="portal.css">
        <script type="text/javascript" src="extjs/ext-all-debug.js"></script>
        <script type="text/javascript" src="app.js"></script>
    </head>
    <body></body>
    </html>
    portal.css
    Code:
    .x-panel-ghost {
        z-index: 1;
    }
    .x-border-layout-ct {
        background: #DFE8F6;
    }
    .x-portal-body {
        padding: 0 0 0 8px;
    }
    .x-portal-column {
        /* columns must have vertical padding to avoid losing dimensions when empty */
        padding: 8px 8px 0 0;
    }
    .x-panel-dd-spacer {
        border: 2px dashed #99bbe8;
        background: #f6f6f6;
        border-radius: 4px;
        -moz-border-radius: 4px;
        margin-bottom: 10px;
    }
    .x-portlet {
        margin-bottom:10px;
        padding: 1px;
    }
    .x-portlet .x-panel-body {
        background: #fff;
    }
    .portlet-content {
        padding: 10px;
        font-size: 11px;
    }
    
    .portlet-content {
        padding: 5px;
        font-size: 12px;
    }
    .settings {
        background-image:url(../shared/icons/fam/folder_wrench.png);
    }
    .nav {
        background-image:url(../shared/icons/fam/folder_go.png);
    }
    .info {
        background-image:url(../shared/icons/fam/information.png);
    }
    app.js
    Code:
    Ext.application({
        name: 'HelloExt',
        launch: function() {
            Ext.create('Ext.container.Viewport', {
                layout: 'fit',
                items: [{
                    id: 'workbench-panel',
                    layout:  {
                        type: 'hbox',
                        align: 'stretch'
                    },
                    items: [{
                        xtype: 'panel',
                        id: "hbp1",
                        cls: "hbpanel",
                        layout:{
                            type: 'vbox',
                            align: 'stretch'
                        },
                        flex: 1,
                        width: 10, height: 10,
                        border: false,
                        items:[{
                            xtype: 'panel',
                            layout: 'fit',
                            id: "hbp1vbp1",
                            title: 'hbp1-vboxpanel1',
                            cls: 'wbpanel vbpanel',
                            flex: 1,
                            width: 10, height: 10,
                            draggable: true,
                            html:"<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce eu egestas diam. Quisque vulputate elementum ligula, ut venenatis orci condimentum quis. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Curabitur suscipit, sapien quis sodales dignissim, ante est commodo nisi, dictum elementum purus orci non tellus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aenean mollis sollicitudin urna, eget mattis est egestas id. Suspendisse sed interdum ante. Proin scelerisque metus nec diam aliquam malesuada. Praesent nibh ante, pharetra nec viverra ut, fermentum a neque.</p> <p>Ut id tellus odio, eget elementum elit. Etiam ut erat ac nunc scelerisque aliquam non a elit. Etiam mollis, elit ut tincidunt dapibus, urna elit auctor velit, nec porta nisl tortor sit amet augue. Curabitur tortor ante, suscipit eget hendrerit ac, consectetur sit amet sem. In rhoncus, tellus quis lobortis commodo, velit risus rhoncus urna, eget posuere felis erat quis libero. Donec eu sodales arcu. Ut et lectus libero, et tristique elit. Donec purus turpis, luctus sed sodales in, porttitor id ligula. Etiam varius vestibulum rutrum. Aenean mollis ultricies sem, non rhoncus metus tempor ut. Aenean laoreet arcu suscipit justo fermentum vulputate.</p>",
                        }],
                    },    {
                        xtype: 'splitter'
                    },     {
                        xtype: 'panel',
                        id: "hbp2",
                        cls: "hbpanel",
                        layout:{
                            type: 'vbox',
                            align: 'stretch'
                        },
                        flex: 1,
                        width: 10, height: 10,
                        border: false,
                        items:[{
                            xtype: 'panel',
                            layout: 'fit',
                            id: "hbp2vbp1",
                            cls: 'wbpanel vbpanel',
                            title: 'hbp2-vboxpanel1',
                            flex: 1,
                            width: 10, height: 10,
                            draggable: true,
                            html:"<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce eu egestas diam. Quisque vulputate elementum ligula, ut venenatis orci condimentum quis. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Curabitur suscipit, sapien quis sodales dignissim, ante est commodo nisi, dictum elementum purus orci non tellus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aenean mollis sollicitudin urna, eget mattis est egestas id. Suspendisse sed interdum ante. Proin scelerisque metus nec diam aliquam malesuada. Praesent nibh ante, pharetra nec viverra ut, fermentum a neque.</p> <p>Ut id tellus odio, eget elementum elit. Etiam ut erat ac nunc scelerisque aliquam non a elit. Etiam mollis, elit ut tincidunt dapibus, urna elit auctor velit, nec porta nisl tortor sit amet augue. Curabitur tortor ante, suscipit eget hendrerit ac, consectetur sit amet sem. In rhoncus, tellus quis lobortis commodo, velit risus rhoncus urna, eget posuere felis erat quis libero. Donec eu sodales arcu. Ut et lectus libero, et tristique elit. Donec purus turpis, luctus sed sodales in, porttitor id ligula. Etiam varius vestibulum rutrum. Aenean mollis ultricies sem, non rhoncus metus tempor ut. Aenean laoreet arcu suscipit justo fermentum vulputate.</p>"
                        },    {
                            xtype: 'splitter'
                        },     {
                            xtype: 'panel',
                            layout: 'fit',
                            id: "hbp2vbp2",
                            cls: 'wbpanel vbpanel',
                            title: 'hbp2-vboxpanel2',
                            flex: 1,
                            width: 10, height: 10,
                            draggable: true,
                            html:"<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce eu egestas diam. Quisque vulputate elementum ligula, ut venenatis orci condimentum quis. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Curabitur suscipit, sapien quis sodales dignissim, ante est commodo nisi, dictum elementum purus orci non tellus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aenean mollis sollicitudin urna, eget mattis est egestas id. Suspendisse sed interdum ante. Proin scelerisque metus nec diam aliquam malesuada. Praesent nibh ante, pharetra nec viverra ut, fermentum a neque.</p> <p>Ut id tellus odio, eget elementum elit. Etiam ut erat ac nunc scelerisque aliquam non a elit. Etiam mollis, elit ut tincidunt dapibus, urna elit auctor velit, nec porta nisl tortor sit amet augue. Curabitur tortor ante, suscipit eget hendrerit ac, consectetur sit amet sem. In rhoncus, tellus quis lobortis commodo, velit risus rhoncus urna, eget posuere felis erat quis libero. Donec eu sodales arcu. Ut et lectus libero, et tristique elit. Donec purus turpis, luctus sed sodales in, porttitor id ligula. Etiam varius vestibulum rutrum. Aenean mollis ultricies sem, non rhoncus metus tempor ut. Aenean laoreet arcu suscipit justo fermentum vulputate.</p>"
                        }]
                    }]
                }],
                
                listeners: {
                    afterrender: function(_this, eOpts){
                    
                        // get all the workbench panels
                        var panels = Ext.get('workbench-panel').select('.wbpanel');
                        
                        // Configure the cars to be draggable
                        var workbenchPanels = Ext.get('workbench-panel').select('.wbpanel');
                        Ext.each(workbenchPanels.elements, function(el) {
                            
                            var dropTarget = new Ext.dd.DropTarget(el, 'wbpanelsDDGroup');
                            
                            var dd = Ext.getCmp(el.id).dd;
                            
                            Ext.dd.DragDropManager.regDragDrop(dd, 'workbenchpanel');
                            
                            dd.onBeforeDrag = function(data, event){
                                _this.origPanelData = data.panel;
                                
                                // get the parent panel
                                _this.origPanelParent = Ext.getCmp(Ext.get(data.panel.id).parent('.x-panel').id);
                                // get the parent of the parent panel
                                _this.origPanelParentParent = Ext.getCmp(_this.origPanelParent.el.parent('.x-panel').id);
                                
                                _this.origPanelIndex = _this.origPanelParent.items.indexOf(data.panel);
                                
                                _this.origPanelDimensions = {
                                    header: {
                                        size: Ext.get(dd.id).down('.x-panel-header').getSize()
                                    },
                                    headerText: {
                                        size: Ext.get(dd.id).down('.x-panel-header-text-container').getSize()
                                    },
                                    boxInner: {
                                        size: Ext.get(dd.id).down('.x-box-inner').getSize()
                                    },
                                    body: {
                                        size: Ext.get(dd.id).down('.x-panel-body').getSize(),
                                        position: Ext.get(dd.id).down('.x-panel-body').getPositioning()
                                    },
                                    panel:{
                                        position: Ext.get(dd.id).getPositioning()
                                    }
                                };
                                
                            };
                            dd.onDrag = function(event){
                                dd.proxy.getProxy().setPositioning(_this.origPanelDimensions.panel.position);
                            };
                            dd.onDragEnter = function(event, id){
                            
                            };
                            dd.onDragOver = function(event, id){
                                
                                //note:
                                // if dragged object is over the left-right side of the element, create a new panel for the parent hbox
                                // if dragged object is over the top-bottom side of the element, create a new panel for the parent vbox
                                
                                // desired offset in pixels
                                var offset = 50;
                                var targetBox = Ext.getCmp(id);
                                var targetBoxPosition = targetBox.el.getXY();
                                var targetBoxSize = targetBox.el.getSize();
                                var mousePosition = event.getXY();
                                
                                var targetBoxParent = Ext.getCmp(targetBox.el.parent('.x-panel').id);                 // and inside each HBox panel is a VBox
                                var targetBoxParentParent = Ext.getCmp(targetBoxParent.el.parent('.x-panel').id);     // the whole workbench area is an HBox
                                
                                var origPanelParent = Ext.getCmp(Ext.get(dd.id).parent('.x-panel').id);
                                var origPanelParentParent = Ext.getCmp(origPanelParent.el.parent('.x-panel').id);
                                
                                
                                if(id != dd.id && targetBox.xtype == 'panel'){
                                        
                                    if(!_this.panelAdded){
                                        // on top
                                        if(mousePosition[1] < targetBoxPosition[1] + offset && mousePosition[1] > targetBoxPosition[1]){
                                            
                                            var targetBoxIndex = targetBoxParent.items.indexOf(targetBox);    
                                            
                                            // check if there's a panel on top of the element and isn't the same id as the dragged panel
                                            // targetBoxIndex - 2: to get panel, 2 elements above the placeholder. the first element is the splitter
                                            if(targetBoxIndex == 0 || targetBoxParent.items.items[(targetBoxIndex - 2)].id != dd.id){
                                            
                                                if(targetBoxIndex <= 0){
                                                    targetBoxIndex = 1;
                                                }
                                                
                                                targetBoxIndex -= 1;
                                                
                                                // create placeholder to drop on to
                                                var newPanel = targetBoxParent.insert(targetBoxIndex, {
                                                    xtype: 'panel',
                                                    layout: 'fit',
                                                    cls: 'wbpanel vbpanel wbplaceholder',
                                                    id: 'wbplaceholder',
                                                    flex: 1,
                                                    draggable: true,
                                                    html:""
                                                });
                                                Ext.dd.DragDropManager.regDragDrop(newPanel.dd, 'workbenchpanel');
                                                
                                                _this.placeholderPanel = newPanel;
                                                
                                                // if the placeholder have siblings, add a splitter
                                                if(targetBoxParent.items.length > 1){
                                                        
                                                    var newPanelIndex = targetBoxParent.items.indexOf(Ext.getCmp(newPanel.id));
                                                    var splitterPosition;
                                                    
                                                    if(newPanelIndex == 0){                     // if placeholder is at the top most
                                                        splitterPosition = newPanelIndex + 1;     // add the splitter below the placeholder
                                                    }else{
                                                        splitterPosition = newPanelIndex;        // add the splitter above the placeholder
                                                        targetBoxIndex += 1;
                                                    }
                                                    
                                                    var newSplitter = targetBoxParent.insert(splitterPosition, {
                                                        xtype: 'splitter'
                                                    });
                                                    _this.addedSplitter = newSplitter;
                                                    _this.addedSplitterIndex = targetBoxParent.items.indexOf(newSplitter);
                                                }
                                                
                                                _this.placeholderIndex = targetBoxIndex;
                                                
                                                _this.placeholderDimensions = {
                                                    size: newPanel.el.getSize(),
                                                    location: newPanel.el.getXY() 
                                                };
                                                
                                                _this.placeholderParent = targetBoxParent;
                                                _this.placeholderParentParent = Ext.getCmp(targetBoxParent.el.parent('.x-panel').id);
                                                
                                                _this.panelAddedTargetParent = 'placeholderParent';
                                                _this.panelAdded = true;
                                            }
                                        }else
                                            
                                        //on bottom
                                        if(mousePosition[1] > (targetBoxPosition[1] + targetBoxSize.height) - offset && mousePosition[1] < (targetBoxPosition[1] + targetBoxSize.height) + offset){
                                            
                                            var targetBoxIndex = targetBoxParent.items.indexOf(Ext.getCmp(id));    
                                            
                                            // check if there's a panel below the element and isn't the same id as the dragged panel
                                            // targetBoxIndex + 2: to get panel, 2 elements below the placeholder. the first element is the splitter
                                            if(targetBoxIndex == targetBoxParent.items.length - 1 || targetBoxParent.items.items[(targetBoxIndex + 2)].id != dd.id){
                                            
                                                // create placeholder to drop on to
                                                var newPanel = targetBoxParent.insert(targetBoxIndex + 1, {
                                                    xtype: 'panel',
                                                    layout: 'fit',
                                                    cls: 'wbpanel vbpanel wbplaceholder',
                                                    id: 'wbplaceholder',
                                                    flex: 1,
                                                    draggable: true,
                                                    html:""
                                                });
                                                Ext.dd.DragDropManager.regDragDrop(newPanel.dd, 'workbenchpanel');
                                                
                                                _this.placeholderPanel = newPanel;
                                                
                                                // if the placeholder have siblings, add a splitter
                                                if(targetBoxParent.items.length > 1){
                                                    
                                                    var newPanelIndex = targetBoxParent.items.indexOf(Ext.getCmp(newPanel.id));
                                                    var splitterPosition;
                                                    
                                                    if(newPanelIndex == targetBoxParent.items.length){     // if placeholder is at the bottom most
                                                        splitterPosition = newPanelIndex;                    // add the splitter above the placeholder 
                                                    }else{
                                                        splitterPosition = newPanelIndex + 1;            // add the splitter below the placeholder
                                                    }
                                                    
                                                    splitterPosition = newPanelIndex;
                                                    
                                                    var newSplitter = targetBoxParent.insert(splitterPosition, {
                                                        xtype: 'splitter'
                                                    });
                                                    _this.addedSplitter = newSplitter;
                                                    _this.addedSplitterIndex = targetBoxParent.items.indexOf(newSplitter);
                                                }
                                                
                                                _this.placeholderIndex = targetBoxParent.items.items.indexOf(Ext.getCmp(newPanel.id));
                                                
                                                _this.placeholderDimensions = {
                                                    size: newPanel.el.getSize(),
                                                    location: newPanel.el.getXY() 
                                                };
                                                
                                                _this.placeholderParent = targetBoxParent;
                                                _this.placeholderParentParent = Ext.getCmp(targetBoxParent.el.parent('.x-panel').id);
                                                
                                                _this.panelAddedTargetParent = 'placeholderParent';
                                                _this.panelAdded = true;
                                            }
                                        }else
                                            
                                        //on left
                                        if(mousePosition[0] < targetBoxPosition[0] + offset && mousePosition[0] > targetBoxPosition[0]){
                                                
                                            var targetBoxParentIndex = targetBoxParentParent.items.indexOf(targetBoxParent);
                                            
                                            // check if there's a panel on top of the element and isn't the same id as the dragged panel
                                            if((targetBoxParentIndex == 0 || targetBoxParentParent.items.items[(targetBoxParentIndex - 2)].id != origPanelParent.id) ||
                                               (targetBoxParentParent.items.items[(targetBoxParentIndex + 2)].id == origPanelParent.id && origPanelParent.items.length > 1)){
                                            
                                                if(targetBoxParentIndex <= 0){
                                                    targetBoxParentIndex = 1;
                                                }
                                                
                                                // create a new panel
                                                var newPanel = targetBoxParentParent.insert(targetBoxParentIndex - 1, {
                                                    xtype: 'panel',
                                                    cls: "hbpanel",
                                                    layout:{
                                                        type: 'vbox',
                                                        align: 'stretch'
                                                    },
                                                    flex: 1,
                                                    border: false,
                                                    items: [{
                                                        xtype: 'panel',
                                                        layout: 'fit',
                                                        cls: 'wbpanel vbpanel wbplaceholder',
                                                        id: 'wbplaceholder',
                                                        flex: 1,
                                                        draggable: true,
                                                        html:""
                                                    }]
                                                });
                                                Ext.dd.DragDropManager.regDragDrop(newPanel.items.items[0].dd, 'workbenchpanel');
                                                
                                                _this.placeholderPanel = newPanel.items.items[0];
                                                
                                                // if the placeholder parent have siblings, add a splitter
                                                if(targetBoxParentParent.items.length > 1){
                                                    
                                                    var newPanelIndex = targetBoxParentParent.items.indexOf(Ext.getCmp(newPanel.id));
                                                    var splitterPosition;
                                                    
                                                    if(newPanelIndex == 0){                        // if the placeholder parent is at the left most
                                                        splitterPosition = newPanelIndex + 1;    // add the splitter at the right of the placeholder
                                                    }else{
                                                        splitterPosition = newPanelIndex;        // add the splitter at the left of the placeholder
                                                    }
                                                    
                                                    var newSplitter = targetBoxParentParent.insert(splitterPosition, {
                                                        xtype: 'splitter'
                                                    });
                                                    _this.addedSplitter = newSplitter;
                                                    _this.addedSplitterIndex = targetBoxParentParent.items.indexOf(newSplitter);
                                                }
                                            
                                                _this.placeholderIndex = targetBoxParentParent.items.items.indexOf(Ext.getCmp(newPanel.id));
                                                
                                                _this.placeholderDimensions = {
                                                    size: newPanel.items.items[0].el.getSize(),
                                                    location: newPanel.items.items[0].el.getXY() 
                                                };
                                                
                                                _this.placeholderParent = newPanel;
                                                _this.placeholderParentParent = Ext.getCmp(newPanel.el.parent('.x-panel').id);
                                                
                                                _this.panelAddedTargetParent = 'placeholderParentParent';
                                                _this.panelAdded = true;
                                            }
                                        }else
                                            
                                        //on right
                                        if(mousePosition[0] > (targetBoxPosition[0] + targetBoxSize.width) - offset && mousePosition[0] < targetBoxPosition[0] + targetBoxSize.width){
                                                
                                            var targetBoxParentIndex = targetBoxParentParent.items.indexOf(targetBoxParent);
                                            
                                            // check if there's a panel on top of the element and isn't the same id as the dragged panel
                                            if((targetBoxParentIndex == targetBoxParentParent.items.length - 1 || targetBoxParentParent.items.items[(targetBoxParentIndex + 2)].id != origPanelParent.id) ||
                                               (targetBoxParentParent.items.items[(targetBoxParentIndex + 2)].id == origPanelParent.id && origPanelParent.items.length > 1)){
                                            
                                                // create a new panel
                                                var newPanel = targetBoxParentParent.insert(targetBoxParentIndex + 1, {
                                                    xtype: 'panel',
                                                    cls: "hbpanel",
                                                    layout:{
                                                        type: 'vbox',
                                                        align: 'stretch'
                                                    },
                                                    flex: 1,
                                                    border: false,
                                                    items: [{
                                                        xtype: 'panel',
                                                        layout: 'fit',
                                                        cls: 'wbpanel vbpanel wbplaceholder',
                                                        id: 'wbplaceholder',
                                                        flex: 1,
                                                        draggable: true,
                                                        html:""
                                                    }]
                                                });
                                                Ext.dd.DragDropManager.regDragDrop(newPanel.items.items[0].dd, 'workbenchpanel');
                                                
                                                _this.placeholderPanel = newPanel.items.items[0];
                                                
                                                // if the placeholder parent have siblings, add a splitter
                                                if(targetBoxParentParent.items.length > 1){
                                                    
                                                    var newPanelIndex = targetBoxParentParent.items.indexOf(Ext.getCmp(newPanel.id));
                                                    var splitterPosition;
                                                    
                                                    splitterPosition = newPanelIndex;                            // add the splitter at the left of the placeholder
                                                                                                
                                                    var newSplitter = targetBoxParentParent.insert(splitterPosition, {
                                                        xtype: 'splitter'
                                                    });
                                                    _this.addedSplitter = newSplitter;
                                                    _this.addedSplitterIndex = targetBoxParentParent.items.indexOf(newSplitter);
                                                }
                                                
                                                _this.placeholderIndex = targetBoxParentParent.items.items.indexOf(Ext.getCmp(newPanel.id));
                                                
                                                _this.placeholderDimensions = {
                                                    size: newPanel.items.items[0].el.getSize(),
                                                    location: newPanel.items.items[0].el.getXY() 
                                                };
                                                
                                                _this.placeholderParent = newPanel;
                                                _this.placeholderParentParent = Ext.getCmp(newPanel.el.parent('.x-panel').id);
    
                                                _this.panelAddedTargetParent = 'placeholderParentParent';
                                                _this.panelAdded = true;
                                            }
                                        }
                                        // remove added panels and splitters
                                        else{
                                            
                                        }
                                    }else{
                                        // check added panel's location and size
                                        
                                        // check for mouse is within the area of the added panel
                                        if(mousePosition[0] > _this.placeholderDimensions.location[0] && 
                                           mousePosition[0] < _this.placeholderDimensions.location[0] + _this.placeholderDimensions.size.width && 
                                           mousePosition[1] > _this.placeholderDimensions.location[1] && 
                                           mousePosition[1] < _this.placeholderDimensions.location[1] + _this.placeholderDimensions.size.height){
                                            // mouse is inside the added placeholder, don't do anything
                                            
                                            _this.insidePlaceholder = true;
                                        }else{
                                            
                                            // remove the placeholder
                                            _this.placeholderParent.remove(_this.placeholderPanel);
                                            if(_this.addedSplitter){
                                                _this.placeholderParent.remove(_this.addedSplitter);
                                            }
                                            
                                            if(_this.placeholderParent.items.length <= 0){
                                                _this.placeholderParentParent.remove(_this.placeholderParent);
                                                _this.placeholderParentParent.remove(_this.addedSplitter);
                                            }
                                            
                                            
                                            _this.placeholderPanel = null;
                                            _this.placeholderIndex = null;
                                            _this.addedSplitter = null;
                                            _this.addedSplitterIndex = null;
                                            _this.placeholderDimensions = null;
                                            _this.placeholderParent = null;
                                            _this.placeholderParentParent = null;
                                            _this.panelAddedTargetParent = null;
                                            _this.panelAdded = false;
                                            _this.insidePlaceholder = false;
                                        }
                                    }
                                }
                                
                            };
                            dd.onDragDrop = function(event, id){
                                
                                var origPanelParent = _this.origPanelParent;
                                var origPanelParentParent = _this.origPanelParentParent;
                                var origPanelData = _this.origPanelData;
                                var origPanelIndex = origPanelParent.items.indexOf(origPanelData);
                                var origPanelDimensions = _this.origPanelDimensions;
                                
                                if(_this.panelAdded){
                                
                                    var placeholderParent = _this.placeholderParent;
                                    var placeholderParentParent = _this.placeholderParentParent;
                                    var placeholderPanel = _this.placeholderPanel;
                                    var placeholderIndex = placeholderParent.items.indexOf(placeholderPanel);
                                    var placeholderDimensions = _this.placeholderDimensions;
                                    
                                    var addedSplitter = _this.addedSplitter;
                                    var addedSplitterIndex = _this.addedSplitterIndex;
                                    
                                    var panelAddedTargetParent = _this.panelAddedTargetParent;
                                    
                                    // get origPanel splitter sibling
                                    if(origPanelParent.items.length > 1){ // check siblings of origPanel
                                        var origPanelSplitter = null; 
                                        
                                        if(origPanelIndex == 0){ // check if origPanel is the first child
                                            origPanelSplitter = origPanelParent.items.items[origPanelIndex + 1];
                                        }else{
                                            origPanelSplitter = origPanelParent.items.items[origPanelIndex - 1];
                                        }
                                        
                                        if(origPanelSplitter.xtype == 'splitter'){
                                            origPanelParent.remove(origPanelSplitter);
                                        }
                                    }
                                    
                                    // check if origPanelParent and placeholderParent panels are the same
                                    // if different, apply insert. Otherwise, move the panel
                                    
                                    if(origPanelParent.id == placeholderParent.id){
                                        // move the old panel to different location
                                        origPanelParent.move(origPanelParent.items.indexOf(origPanelData) , placeholderIndex);
                                    
                                    }else{
                                        // insert the old panel to different location
                                        placeholderParent.insert(placeholderIndex, origPanelData);
                                        
                                        // remove the old panel from the old location
                                        origPanelParent.remove(origPanelData);
                                    }
                                    
                                    // remove the placeholder
                                    placeholderParent.remove(placeholderPanel.id);
                                    
                                    // check if parent panel is empty, then remove parent panel
                                    if(origPanelParent.items.items.length <= 0){
                                        
                                        var origPanelParentIndex = origPanelParentParent.items.indexOf(origPanelParent);
                                        var origPanelParentSplitter = null; 
                                        
                                        if(origPanelParentIndex == origPanelParentParent.items.length - 1){ // check if origPanelParent is last child
                                            origPanelParentSplitter = origPanelParentParent.items.items[origPanelParentIndex - 1];
                                        }else{
                                            origPanelParentSplitter = origPanelParentParent.items.items[origPanelParentIndex + 1];
                                        }
                                        
                                        if(origPanelParentSplitter.xtype == 'splitter'){
                                            origPanelParentParent.remove(origPanelParentSplitter);
                                        }
                                        
                                        origPanelParentParent.remove(origPanelParent.id);
                                    }
                                    
                                    
                                    if(origPanelParent.id == placeholderParent.id){
                                        // resize moved panel because it disappears after moving
                                        //Ext.get(origPanelData.id).setSize(placeholderDimensions.size);
                                        Ext.get(origPanelData.id).down('.x-panel-header').setSize(origPanelDimensions.header.size);
                                        Ext.get(origPanelData.id).down('.x-panel-header-text-container').setSize(origPanelDimensions.headerText.size);
                                        Ext.get(origPanelData.id).down('.x-box-inner').setSize(origPanelDimensions.boxInner.size);
                                        Ext.get(origPanelData.id).down('.x-panel-body').setSize(origPanelDimensions.body.size);
                                        Ext.get(origPanelData.id).down('.x-panel-body').setPositioning(origPanelDimensions.body.position);
                                    }else{
                                        // resize moved panel because it disappears after moving
                                        Ext.get(origPanelData.id).setSize({
                                            width: '100%', 
                                            height: placeholderDimensions.size.height
                                        });
                                        
                                        Ext.get(origPanelData.id).down('.x-panel-header').setSize({
                                            width: '100%',//placeholderDimensions.size.width,
                                            height: origPanelDimensions.header.size.height
                                        });
                                        
                                        Ext.get(origPanelData.id).down('.x-panel-header-text-container').setSize({
                                            width: '100%', //placeholderDimensions.size.width - 11,
                                            height: origPanelDimensions.headerText.size.height
                                        });
                                        
                                        Ext.get(origPanelData.id).down('.x-box-inner').setSize({
                                            width: '100%',//placeholderDimensions.size.width - 1,
                                            height: origPanelDimensions.boxInner.size.height
                                        });
                                        
                                        Ext.get(origPanelData.id).down('.x-panel-body').setSize({
                                            width: '100%',//placeholderDimensions.size.width,
                                            height: placeholderDimensions.size.height - 25,
                                        });
                                        
                                        Ext.get(origPanelData.id).down('.x-panel-body').setPositioning(origPanelDimensions.body.position);
                                    }
                                    
                                    _this.panelAdded = false;
                                }else{
                                    Ext.get(dd.id).down('.x-panel-header').setSize(origPanelDimensions.header.size);
                                    Ext.get(dd.id).down('.x-panel-header-text-container').setSize(origPanelDimensions.headerText.size);
                                    Ext.get(dd.id).down('.x-box-inner').setSize(origPanelDimensions.boxInner.size);
                                    
                                    Ext.get(dd.id).down('.x-panel-body').setSize(origPanelDimensions.body.size);
                                    Ext.get(dd.id).down('.x-panel-body').setPositioning(origPanelDimensions.body.position);
                                }
                                
                            };
                            dd.onDragOut = function(event, id){
                                if(!_this.insidePlaceholder){
                                    if(_this.panelAdded){
                                        _this.placeholderParent.remove(_this.placeholderPanel);
                                        
                                        if(_this.addedSplitter){
                                            _this.placeholderParent.remove(_this.addedSplitter);
                                        }
                                        
                                        _this.placeholderPanel = null;
                                        _this.placeholderIndex = null;
                                        _this.addedSplitter = null;
                                        _this.addedSplitterIndex = null;
                                        _this.placeholderDimensions = null;
                                        _this.placeholderParent = null;
                                        _this.placeholderParentParent = null;
                                        _this.panelAddedTargetParent = null;
                                        _this.panelAdded = false;
                                    }
                                }
                            };
                            dd.onInvalidDrop = function(event){
                            
                            };
                        });
                    }
                }
            });
        }
    });
    There's also a bug there that after you drop a panel, it disappears (or at least just turn into a small square). I fixed it by resizing the panel after it is dropped.

    This is almost perfect, I just need your help to fix the issue I'm having troubled with.
    I'm not even sure if I really did this properly. If there's a better way to do it, please tell me.


    OS: Windows XP SP3
    Browsers: Firefox 12.0, Chrome, Safari 5 (I think you can see it in all browsers)
    ExtJs ver: 4.0.7


    Thanks a lot!
    Last edited by Lionlancer; 24 May 2012 at 3:05 AM. Reason: More info added

  2. #2
    Sencha User
    Join Date
    Mar 2012
    Posts
    12
    Vote Rating
    0
    Lionlancer is on a distinguished road

      0  

    Default


    Can anyone answer this? :s

    The scripts are all working and ready for testing. Some pointers or ideas might help.

    Also, I think this is a bug of Ext, not just mine. I don't even see an error in the console. :(

    I really appreciate all the help I can get. :)

  3. #3
    Sencha - Support Team scottmartin's Avatar
    Join Date
    Jul 2010
    Location
    Houston, Tx
    Posts
    9,110
    Answers
    678
    Vote Rating
    470
    scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future

      0  

    Default


    Please upgrade to 4.1. There were many layout issues in 4.07

    Regards,
    Scott.

  4. #4
    Sencha User
    Join Date
    Mar 2012
    Posts
    12
    Vote Rating
    0
    Lionlancer is on a distinguished road

      0  

    Default An error occured

    An error occured


    Thanks scottmartin.

    Ok, I upgraded to 4.1, now I'm getting an error:

    oDD is undefined
    http://<test-url-here>/extjs-4.1.0/ext-all-debug.js
    Line 27794
    this.ids[sGroup][oDD.id] = oDD;

    The error starts from this part of the code in app.js, line 83
    Code:
    var dropTarget = new Ext.dd.DropTarget(el, 'wbpanelsDDGroup'); 
    var dd = Ext.getCmp(el.id).dd; 
    Ext.dd.DragDropManager.regDragDrop(dd, 'workbenchpanel');
    var dd is undefined.

    It seems dd is not automatically created after I assigned the element as a drop target.

    What should I do to fix it? Am I really coding it all wrong?

    I really want to have access to methods such as onDrag, onDragEnter, onDragOver, etc because I want to know what are the current element under the mouse while I'm dragging a panel (unless, there really is a better way than what I'm doing).

    I appreciate all the help I can get. Suggestions are also welcome!

    Edit:
    listening to afterlayout works, but there's still layout issues. I still have to check if I can fix it. I'm still open to suggestions.

  5. #5
    Sencha User
    Join Date
    Mar 2012
    Posts
    12
    Vote Rating
    0
    Lionlancer is on a distinguished road

      0  

    Default Worse

    Worse


    Bummer, it seems my code isn't compatible with the latest version...

    Using the latest version (4.1):
    - Why does my script can't run properly on afterrender event?
    - I put it on afterlayout, it works but it is a mess... why?
    - On what event should my script listen to for it to run properly?
    - You said, it fixed a lot of layouting issues. I didn't extended the classes, then why I'm getting a lot of layouting issues now (usually after moving the panel during D&D)?
    - What did I do wrong in the script?

    Can anyone answer my questions? So that it'll give me ideas on what to do... I've been working on it for weeks...

    My script is almost perfect in 4.0.7... but 4.1 ruined it all...

  6. #6
    Sencha - Support Team scottmartin's Avatar
    Join Date
    Jul 2010
    Location
    Houston, Tx
    Posts
    9,110
    Answers
    678
    Vote Rating
    470
    scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future

      0  

    Default


    Can you create a small isolated test case where the layout working in 4.07 and does not in 4.1?

    As mentioned, there were many changes from 4.07 .. that actually contained many problems. It may be in fact how you code it structured.

    Let started with one of your layouts that you feel should be working and we can grow from there.

    Regards,
    Scott.

  7. #7
    Sencha User
    Join Date
    Mar 2012
    Posts
    12
    Vote Rating
    0
    Lionlancer is on a distinguished road

      0  

    Default


    Thanks Scott!

    If you tried my code, the layout is fine in the initial run BUT my script (for drag and dropping panels) doesn't work if I apply it in "afterrender" event in 4.1 (the screen is blank and there's an error: oDD is undefined, which should be the dd of the panel after I assigned it as a drop target). If I apply it to "afterlayout" event though, it works but the panel doesn't snaps itself in the right place (where I added a placeholder panel for the dragged panel to drop on to, I'm trying to imitate the portal demo).

    Ok, I'll attach another scripts but this time, there's no listener included to apply drag and drop. We will only focus on layouting alone. I will attach scripts that focuses on adding the drag and drop in the event listener later.

    For HBox layout
    Code:
    Ext.application({
        name: 'HelloExt',
        launch: function() {
            Ext.create('Ext.container.Viewport', {
                layout:  { type: 'vbox', align: 'stretch' },
                items: [{
                    id: 'main-hbox',
                    xtype: 'panel',
                    layout:{ type: 'hbox', align: 'stretch' },
                    flex: 1,
                    //maintainFlex: true,
                    items: [{
                        xtype: 'panel',
                        title: 'HBox',
                        layout: 'fit',
                        flex: 1,
                        //maintainFlex: true,
                    
                    }]    
                }, {
                    
                    id: 'controls',
                    xtype: 'panel',
                    bodyStyle: 'padding:5px',
                    items:[{
                        xtype: 'button',
                        margin: 5,
                        text: 'Add New HBox',
                        handler: function(){
                            var parentCmp = Ext.getCmp('main-hbox');
                            var hboxes = Ext.get(parentCmp.id).select('.sub-hbox');
                            var count = 1;
                            
                            Ext.each(hboxes.elements, function(el) {
                                count++;
                            });
                            
                            // create a new panel
                            var newItems = parentCmp.add([{
                                xtype: 'splitter'
                            }, {
                                title: 'Hbox '+ count +' (added)',
                                xtype: 'panel',
                                cls: "sub-hbox",
                                layout:{ type: 'hbox', align: 'stretch' },
                                flex: 1
                            }]);
                        }
                    }]
                    
                }]
    
            });
        }
    });
    For VBox layout
    Code:
    Ext.application({
        name: 'HelloExt',
        launch: function() {
            Ext.create('Ext.container.Viewport', {
                layout:  { type: 'vbox', align: 'stretch' },
                items: [{
                    id: 'main-vbox',
                    title: 'VBox',
                    xtype: 'panel',
                    layout:{ type: 'vbox', align: 'stretch' },
                    flex: 1,
                    //maintainFlex: true,
                    items: [{
                        xtype: 'panel',
                        layout: 'fit',
                        flex: 1,
                        //maintainFlex: true
                    }]    
                    
                }, {
                
                    id: 'controls',
                    xtype: 'panel',
                    bodyStyle: 'padding:5px',
                    items:[{
                        xtype: 'button',
                        margin: 5,
                        text: 'Add New VBox',
                        handler: function(){
                            var parentCmp = Ext.getCmp('main-vbox');
                            var vboxes = Ext.get(parentCmp.id).select('.sub-vbox');
                            var count = 1;
                            
                            Ext.each(vboxes.elements, function(el) {
                                count++;
                            });
                            
                            // create a new panel 
                            var newItems = parentCmp.add([{
                                xtype: 'splitter'
                            }, {
                                title: 'Vbox '+ count +' (added)',
                                xtype: 'panel',
                                cls: "sub-vbox",
                                layout:{ type: 'vbox', align: 'stretch' },
                                flex: 1
                            }]);
                            
                        }
                    }]
                }]
                
            });
        }
    });
    These can demonstrate the bug I am seeing while adding panels to hbox or vbox. Try adding a new panel and adjust its size before adding a new one. This is one of my problems after moving a panel via drag and drop. Try testing them in 4.0.7 and 4.1, you will see the bug is present in both versions, except if you include maintainFlex: true in one of the panels, the layouting is fine on 4.0.7.

    This is the simplest I can do, I hope it can help you figure out the problem.

    Thanks a lot!

  8. #8
    Sencha User
    Join Date
    Mar 2012
    Posts
    12
    Vote Rating
    0
    Lionlancer is on a distinguished road

      0  

    Default


    Any thoughts from the Sencha Devs? If we can solve the issue I am having, it will benefit a lot of users who plan to build a windows like rearrangement of panels.

    So I hope anyone can help me. I also see a lot of issues while I'm building the app.

    Thanks a lot!

  9. #9
    Sencha User
    Join Date
    Mar 2012
    Posts
    12
    Vote Rating
    0
    Lionlancer is on a distinguished road

      0  

    Default anybody?

    anybody?


    It seems noone can help me now..

    Is what I'm trying to do impossible to achieve (at least in the current version of ExtJS)? Or am I not clear in explaining what I wanted to do in the first place?

    Anyway, can anyone teach me how to override HBoxLayout and VBoxLayout? I want to override how it calculates the size of the its child components and also apply their correct position. Is this possible? If so please, show me an example.

    I really appreciate all the help I can get.
    Thanks in advance!

  10. #10
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,508
    Answers
    13
    Vote Rating
    56
    Animal has a spectacular aura about Animal has a spectacular aura about Animal has a spectacular aura about

      0  

    Default


    You will have to handle re-inserting the Panel at any new point in your DD handling code.

    draggable just enables the DIV to be moved, and then potentially informs you when the user releases the mouse.

    What happens after that is always application-specific, so the application has to implement it.

    In your case it looks like you might want to remove the dragged panel from its original position in its Container and insert it at a new position.

    Box layouts work in 4.1.1.

Thread Participants: 2

Tags for this Thread