Announcement

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

    Arrange Images in Grid

    HI ,

    How can I arrange(auto arrange) images in a grid when I drop images in a container.I am able to arrange vertically using VStack or horizontally using HStack
    Last edited by skota; 6 Nov 2006, 10:44.

    #2
    Hi skota,

    Can you clarify:

    1) do you want the user to be able to drop images in particular positions, or are new images just added at the end?

    2) is the grid fixed size, or will it expand vertically and begin scrolling if the user keeps adding images? can the user expand the grid horizontally?

    3) can the user leave gaps, for example, an image on row 1, then none on row 2, then one on row 3?

    Comment


      #3
      Please check the below picture
      http://repository.cricnjoy.com/CnJTmpl/mockups/ResourceAlbum-modified8.jpg

      In this top area is where images getted added. It needs to be added as flow layout by default in the end. From left to right and top to bottom. Where depending upon the outer container dimensions it automatically should decide the number of columns to position and we want to have only vertical scrollbar but not horizontal scrollbar.

      With in the dropped container the thumbnails are positions sorted by Date but the order of the items can be rearranged as needed by moving items with in the panel.

      Also to your third question on gaps...the answer is no...we don;t want gaps, when an items is moved around the spot should be occupied by next item and when we are trying the items to else where we want to have item to highlight so that user can drop there to take its place. and the previous item where new item drops moves to next slot, but the removed item slot should be automatically adjusted.

      See the below example:
      http://wiki.script.aculo.us/scriptaculous/page/print/SortableFloatsDemo
      Also please check flickr interface where we can find similar behaviour.

      Thanks

      Comment


        #4
        any solution of this post?

        Comment


          #5
          simple matrix component

          Hi skota -

          Take a look at the following complete example that includes a simple Matrix component composed of SmartClient layouts. Try dragging the images at the top into the auto-expanding matrix below them. Take a look at the Matrix class definition and comments.

          This doesn't implement all the features you need, but I believe it has enough example code that you can implement the remainder.

          Let me know what you think:

          Code:
          <!-- Copyright (c)2003 Isomorphic Software, Inc. (www.isomorphic.com) All rights reserved. -->
          <HTML><HEAD>
          	<SCRIPT>var isomorphicDir="../../isomorphic/";</SCRIPT>
              <SCRIPT SRC=../../isomorphic/system/modules/ISC_Core.js></SCRIPT>  
              <SCRIPT SRC=../../isomorphic/system/modules/ISC_Foundation.js></SCRIPT>  
              <SCRIPT SRC=../../isomorphic/system/modules/ISC_Containers.js></SCRIPT> 
          	 <SCRIPT SRC=../../isomorphic/skins/SmartClient/load_skin.js></SCRIPT> 
          </HEAD><BODY BGCOLOR='papayawhip' MARGINHEIGHT=0 MARGINWIDTH=0 LEFTMARGIN=0 TOPMARGIN=0>
          
          <!--------------------------
            Example code starts here
          ---------------------------->
          
          <SCRIPT>
          //
          // Simple Matrix class - a VStack of HStacks that allows Canvii to be dropped in
          //-----------------------------------------------------------------------------------------
          isc.defineClass("Matrix", "VStack").addProperties({
          
          // These two properties work in tandem.  When autoShowEmptyRowWhenFull is set to true, we'll
          // show an empty HStack below the last row when the previous HStack has a number of members
          // equal to or greater than numCols.  In effect, this auto-creates a new row to be used as a
          // drop target when the last row is full.
          numCols: 3,
          autoShowEmptyRowWhenFull: true,
          
          border: "1px solid red",
          layoutMargin: 10,
          membersMargin: 10,
          
          // This is the class we'll create for new rows
          rowClass: "HStack",
          
          // These are the properties we'll use for the rowClass by default
          rowDefaults : {
              border: "1px solid black",
              autoDraw: false,
              canAcceptDrop: true,
              dropLineThickness: 1,
              membersMargin: 10,
              layoutMargin: 10,
              height: 60,
          
              // whenever components are added or removed, notify the outer VStack so it can auto-create
              // or auto-destroy the last empty row as appropriate.
              addMember: function () {
                  this.Super("addMember", arguments);
                  this.container.dataChanged();
              },
              removeMember: function () {
                  this.Super("removeMember", arguments);
                  this.container.dataChanged();
              }
          },
              
          
          initWidget : function () {
              this.Super("initWidget", arguments);
          
              // can take an initial set of data - format is array of arrays where the inner arrays are
              // rows that contain Canvii
              this.setData(this.data);
          },
          
          setData : function (data) {
              // if we have data, destroy the member arrays (but not their contents) so we don't leak
              // them
              if (this.members) {
                  for (var i = 0; i < this.members.length; i++) {
                      var row = this.members[i];
                      row.removeMembers(row.getMembers());
                      row.destroy();
                  }
              }
          
              // create member HStacks for rows and populate them with the passed in Canvii
              if (data) {
                  // each entry is an array containing items to be placed in an HStack in that row.
                  for (var i = 0; i < data.length; i++) {
                      var rowData = data[i];
          
                      // create a new member row
                      var row = this.createNewRow();
          
                      // add the row to our VStack
                      this.addMember(row);
          
                      for (var j = 0; j < rowData.length; j++) {
                          // add the item to the row
                          row.addMember(rowData[j]);
                      }
                  }
              }
              this.data = null;
          
              this.dataChanged();
          }, 
          
          // this is called whenever members are added or removed on the HStack members
          dataChanged : function () {
              var members = this.getMembers();
          
              // remove any empty rows in the grid except last row - that case is handled below
              for (var i = 0; i < members.length; i++) {
                  var row = members[i];
                  if (row.getMembers().length == 0 && i+1 < members.length-1) {
                      row.destroy();
                      i--;
                  }
              }
          
              // automatically add or remove the last row based on how the previous row's member length
              // compares to our numCols setting
              if (this.autoShowEmptyRowWhenFull) {
                  var lastRow = members[members.length-1];
          
                  // if the lastRow's member length is equal to or exceeds the numCols setting, create a
                  // new empty HStack so that items can be dropped into it.
                  if (!lastRow || lastRow.getMembers().length >= this.numCols) {
                      var emptyRow = this.createNewRow();
                      this.addMember(emptyRow);
                  } else if (lastRow && lastRow.getMembers().length == 0) {
                      // if the last row is an empty row and the row before has space (member length <
                      // numCols), then destroy the empty last row since the user can drop into the
                      // previous row instead.
                      if (members.length-2 >= 0 && members[members.length-2].getMembers().length < this.numCols) {
                          lastRow.destroy();
                      }
                  }
                  
              }
          },
          
          // creates a new empty HStack from the config properties set on this class
          createNewRow : function () {
              // Note: adds our ref as the 'container' property so that these class instances can call
              // this.container.dataChanged()
              return isc.ClassFactory.getClass(this.rowClass).create(this.rowDefaults, {container: this});
          },
          
          // XXX not implemented - APIs to add/remove members at particular positions
          add : function (x, y) {
          
          },
          
          remove : function (x, y) {
          
          }
          
          });
          // End of Matrix class
          
          
          
          
          // Test code
          //-----------------------------------------------------------------------------------
          isc.Img.create({
              width:48, height:48,
              src: "/isomorphic/system/reference/exampleImages/pieces/48/cube_blue.png",
              canDrag: true,
              canDrop: true
          });
          
          isc.Img.create({
              left: 50,
              width:48, height:48,
              src: "/isomorphic/system/reference/exampleImages/pieces/48/cube_green.png",
              canDrag: true,
              canDrop: true
          });
          
          isc.Img.create({
              left: 100,
              width:48, height:48,
              src: "/isomorphic/system/reference/exampleImages/pieces/48/cube_yellow.png",
              canDrag: true,
              canDrop: true
          });
          
          
          isc.Img.create({
              left: 150,
              width:48, height:48,
              src: "/isomorphic/system/reference/exampleImages/pieces/48/pawn_blue.png",
              canDrag: true,
              canDrop: true
          });
          
          isc.Img.create({
              left: 200,
              width:48, height:48,
              src: "/isomorphic/system/reference/exampleImages/pieces/48/star_red.png",
              canDrag: true,
              canDrop: true
          });
          
          isc.Matrix.create({
              ID: "matrix",
              left: 50,
              top: 50,
              data: [
                  [
                      isc.Img.create({
                          width:48, height:48,
                          src: "/isomorphic/system/reference/exampleImages/pieces/48/cube_frame.png",
                          canDrag: true,
                          canDrop: true
                      })
                  ]
              ]
          });
          
          
          </SCRIPT>
          
          
          
          
          </SCRIPT>
          </BODY>
          </HTML>

          Comment


            #6
            http://apache.cricnjoy.com/simpics/SmartClient/smartclientSDK/examples/myAtoks/prototype2.html

            Please check the above link. We fixed few performence issues.

            Regarding the Grid Layout:

            It would be best if the implementation has some flow layout component defined.
            for example the example code given by you.
            http://apache.cricnjoy.com/simpics/SmartClient/smartclientSDK/examples/myAtoks/example.html
            we have to write the flow layout (currently you have VLayout and HLayout), it would be best if there is FlowLayout, where when window is resized automatically it calculates the number of columns in a row and redraws the container by rearranging the items. The way it should happen is with out flickr and done automatically. It is best if the layout manager is build from core instead of we building it, as eventually we will face refresh problems when repainting the items on resize of the window.
            Best example for this is flickr interface, when we add many images and resize the window, even before resize is in progress it calculates the number of cells that can be positioned inside the row and automatically rearranges it making it very dynamic. The problem we are trying to solve is initial layout similar to flow layout. infact we want to use it similar to
            http://apache.simcricket.com/simpics/SmartClient/smartclientSDK/examples/animation/portal_animation.html
            where when an item is dropped automatically the arrangement should happen
            But only diffeence is here it is columns based we need to extend this behaviour to flow based, with out a flick to the screen. The most important is resizing it should trigger the recalculation of the View using double buffering techniques.

            We would greatly appreciate if you can give us pointers how to implement the Flowlayout, as we are spending too much time figuring out the right solution with out getting screen refresh problems. It would be best if more layouts like in AWT are provided to the platform rather than we implement them, which will be error prone and cannot easily avoid refresh issues.

            Thanks,
            -SK

            Comment


              #7
              Hi skota,

              Running the example we provided in IE and Firefox I'm not able to see any "refresh problems". Could you describe what you are seeing? Nothing about this usage should require special code or special rendering techniques.

              The code you need to add to get the rest of the behaviors you want is straightforward. In the provided example, the setData() method will rearrange the images in rows according to the numCols setting. To implement the behavior you described, when the component is resized (which you can detect by overriding Canvas.resizeBy), simply change the numCols setting based on the current width and call setData().

              Comment

              Working...
              X