wiki:PAGE_ELEMENT_GROUPING_R0

Version 6 (modified by peko, 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

The idea is to have groups of page elements in the model. Selecting page elements is one thing and creating a group of the selected elements is the thing that this task is about. Grouped elements should be persisted and restored when opening the book. A page element should be part of no group or one group only - page elements cannot be part of different groups.

Task requirements

  • Define how grouping should be introduced in the model.
  • Save groups along with the book.
  • Load groups along with the book.
    • 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).

Task result

  • code

Implementation idea

  • In the class for page in the model, create a value list property containing groups of elements.
  • Implement the group of elements as s class.
    • It should be able to contain different kinds of elements.
    • 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_PAGE_ELEMENTS_GROUP_ALIGN_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 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.
    • The Page would also implement the GroupContainer interface.
    • 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.

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.