wiki:PAGE_ELEMENT_GROUPING_R0

Version 14 (modified by kyli, 16 years ago) (diff)

--

Error: Macro BackLinksMenu(None) failed
compressed data is corrupt

Error: Macro TicketQuery(summary=PAGE_ELEMENT_GROUPING_R0, format=table, col=summary|owner|status|type|component|priority|effort|importance, rows=description|analysis_owners|analysis_reviewers|analysis_score|design_owners|design_reviewers|design_score|implementation_owners|implementation_reviewers|implementation_score|test_owners|test_reviewers|test_score|) failed
current transaction is aborted, commands ignored until end of transaction block

Analysis

Overview

Every book view has a work area related to it. It must contain the corresponding page, as well as the book extras, attached to it. Pages can contain frames or groups of frames. Extras probably will have similar abilities in the near future.

  • The groups should be a method for organizing frames and other groups for easy manipulation - for example, we can group several frames to move/resize them together, change their background, etc. If we go further, groups should contain frames and/or other groups. (There is tree structure here) Also moving, rotating and resizing one group should effect the entire group. All of the child's of a group should remain their relative position, rotations and sizes. Visual result should be like they are stuck together.
  • Grouping 2 elements (groups an/or frames) together means making a group, containing both of them.
  • Ungrouping of group is detaching its top-level elements from each other.
  • Groups should not contain both frames and stickies (for example), so it would be better if book extras were at the same grouping level as the page itself.
  • A page element (frame, sticky, etc.) can be in only one group at one time.
  • Create and break a book could be done in following way after selecting a element or elements.
    • Halo buttons.
    • Short keys
      • ctrl + g for creating a group
      • ctrl + b for braking a group
      • Double click on group for edit her
    • From the edit menu should be section for groups with create, edit, and break buttons.
    • NOTE: If user selects for example 2 groups and 2 frames and press ctrl + b. This action will break(grouping) the 2 groups but won't have effect over the frames.
    • Every group of page elements (not for book extras) has a timeline.

Task requirements

  • Define how grouping should be introduced in the model.
    • Groups must be persistable along with the book.
    • Groups must not conflict with the current template model.
    • A group cannot contain both frames and extras.
    • If a group is loaded it should be represented as selected elements in the view.
  • Create a halo button that will create a group of elements from the currently selected ones when clicked in the view.
  • Create a halo button for ungrouping if a group of elements is selected in the view - it should ungroup the elements.
    • Ungrouping should be done in reverse order of grouping. If a group is firstly is constructed of two groups, ungrouping should divide the elements to those groups used in the beginning. This means that ungrouping is not dividing the group to separate elements but to previous state of the elements(grouped or separate).
  • Z-order issues could be postponed for the "main" revision.
  • Provide short cuts and menu buttons for manipulation(create, edit, break) over the groups.

Task result

  • code

Implementation idea

  • Get into the current group model, get familiar with its negatives.
  • Watch this video, see the new design ideas for the grouping.
  • Use the current tests written for grouping.
  • In order to make a group persistable, it would be best to be implemented as a resource.
    • It may contain different properties that are common for the group like background(for background supported elements), border color, border size etc.
    • It may have a size and position. This is the bounding rectangle for the elements in the group.

PAGE_ELEMENT_MULTI_MANIPULATION_R0
PAGE_ELEMENT_MULTI_SELECT_R0
PAGE_ELEMENT_ALIGNING_R0
GROUP_TIMELINES_R0

How to demo

  • Open sophie2.
  • Select several elements by clicking them.
  • Click the group elements halo button.
  • Click elsewhere.
  • Clicking on an element from the group should select all the elements.
  • Save the book.
  • Open the book.
  • When clicking on a element that is part of the previously created group the whole group should be selected.
  • Ungroup the group.
  • Clicking on an element should select only that element.

Design

  • Grouping in most applications has the following behavior:
    • Grouping of groups:
      • Grouping some elements creates a group.
      • Grouping some other elements creates another group.
      • Selected the first group and then the second one and grouping them creates one group of the former two.
      • Ungrouping the lastly created group will return back to the state where we have two groups, since it had been created from these two groups.
    • Grouping of groups and elements:
      • If we have a group and several ungrouped elements, select them all and group them, we will end up having a large group of all the elements from the group along with the elements that were previously ungrouped.
      • Ungrouping the former group we will end up having the first group and the ungrouped elements.
  • Note: Current design is done on behalf that we group Frames, but it can be changed quickly to support all kinds of page elements.
  • For the grouping to behave properly we should define a tree of groups and elements.
    • Define an interface ElementContainer with the following methods:
      • Prop<? extends ??> parentContainer(), providing the parent container of this element.
      • RwListProp<PageElement> elements(), all the elements that a class implementing should provide.
    • Define an interface GroupContainer with the following methods:
      • Prop<? extends GroupContainer> parentContainer(), providing the parent GroupContainer of the class implementing it.
      • RwListProp<Group> containers(), all the containers that a class implementing should provide.
    • Define a class Group which will handle grouping and ungrouping of frames. It will implement the GroupContainer, ElementContainer and will extend Resource.
    • The Page would also implement the GroupContainer interface.
    • The Frame will implement ElementContainer.
    • The parentContainer of the Group will be a Page. This means that the Group whose parent container is a Page is a root group. It also provides a list of containers that are Groups. The Group class will also contain a list of frames that are grouped in this group.
    • Page will not have a parentContainer. It will be initially set to null.
    • All this will force a parent<=>child relationship that is manually controlled from within the Group class.
    • The Group class should have two static methods which will do exactly what is supposed for grouping of elements:
      • public static Group createGroup(Page page, List<Frame> frames) - which will create a Group of elements and make it the root group (its parent container should be the page).
      • public static void deleteGroup(Group group) - which will ungroup a previously created group. (the examples explained above).
    • The Frame class should be able to provide a parentContainer - the Group that it is part of, or null if it is not grouped.
      • The parentContainer will be an auto property that depends on a container value property with package visibility. This way no grouping and stuff will be done except from the Group class.
  • Examples:
    • Grouping three frames will end up having the following tree in the model:
      			    page
       			    /	\
       			   /	 \
       			  /	  \
       		   @Own-ed	groups(size==1)
       		   frames	/
       		               /
       			      /	
       			    group[0]
       			    /      \
       			   /	    \
       		frames(size==3)	groups(size==0) 
       		    / |  \	
       		   /  |   \
       		  /   |    \
                       /    |     \
       	    frame1  frame2  frame3
      
    • Note that we do not change the own-ed frames in the Page. We have one group and clicking on either frame should select all the group.
  • The actual grouping control will be done through the HaloButtons created for this.
    • Selected elements will be able to be grouped.
    • Selected group will be able to be ungrouped.
    • Both halo buttons will appear on selecting more than one frame.
  • There was another design considered => see Comments section.

New design

  • Define an interface ElementContainer which will contain elements. It will have the following methods:
    • Prop<ElementContainer> parentContainer(), providing the parent container of this one.
    • RwListProp<PageElement> elements(), all the elements that this container owns.
  • Define an interface GroupContainer which contains Groups. It will have the following methods:
    • Prop<GroupContainer> parentContainer(), providing the parent GroupContainer of the class implementing it.
    • RwListProp<Group> groups(), all the groups this container owns.
  • The Page will implement GroupContainer - it will have grou(s) of frames / of other groups. Page will not have a parentContainer - it will be initially set to null. The Group whose parent container is a Page is a root group.
  • The Frame will implement ElementContainer - it will have parent ElementContainer - a group.
  • Define class Group which will handle grouping, ungrouping and group navigation. It will implement the GroupContainer, ElementContainer and will extend Resource. The Group class should have two static methods which will do exactly what is supposed for grouping of elements:
    • public static Group createGroup(Page page, List<Frame> frames) - which will create a Group
    • public static void deleteGroup(Group group) - which will ungroup a previously created group.
    • void enterGroup() - which will set the current group to this one and view it as a root group.
    • void exitGroup() - which will go one level up in the group tree. If the current group is a root one, does nothing.
  • Examples:
    • Grouping three frames will end up having the following tree in the model:
      		        	    page
       			             |
                   			     |
       		         	     |
                                        @Own-ed 
                		      groups(size==1)
      	                  	/
      	                       /
               		      /	
      	        	    group[0]
      		            /      \
               		   /	    \
                             @Own-ed       @Own-ed                                 
                        elements(size==3)  groups(size==0) 
      	               / |  \	
                            /  |   \
            	             /   |    \
                          /    |     \
                    frame1  frame2  frame3
                        /       |       \
                       /        |        \
                      /         |         \
               @Own-ed        @Own-ed      @Own-ed
      elements(size=0)  elements(size=0)   elements(size=0)
          
      
  • Note that we do not change the own-ed frames in the Page. We have one group and clicking on either frame should select all the group.
  • The actual grouping control will be done through the HaloButtons created for this.
    • Selected elements will be able to be grouped.
    • Selected group will be able to be ungrouped.
    • Both halo buttons will appear on selecting more than one frame.

Implementation

(Implementation results should be described and linked here (from the wiki or the repository))

Testing

Comments

  • We introduce a parent-child relationship but this will be quite radical, since the Frame has a parent Page while the Page has a parent Book.
    • Having a parent-child relationship will enforce to have something in between the Frame and Page. If the Frame is @Own by something other than the Page it will enforce to change the model so that other things that depend on Page<=>Frame, parent<=>child relationship will require more computations. Besides grouping of frames is only for selecting and editing purposes.