wiki:PAGE_STRUCTURE_PALETTE_R0
Last modified 15 years ago Last modified on 11/04/09 16:28:28

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

Error: Macro TicketQuery(summary=PAGE_STRUCTURE_PALETTE_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

(Give as much as possible of the needed information for designing and implementing the task in the following sections.)

Overview

The page structure palette shows a tree of all the objects on a current page.

Task requirements

  • Create a Page Structure palette in the Pages tab, which is in the left flap.
  • Create a tree, according to the following requirements:
  • The root node of the displayed tree should be the current page.
  • Children nodes:
    • Non grouped frames (display the name, for example "Frame A"; in brackets frame type;)
      • Properties
        • Resource name and/or id
        • Size
        • Location
      • Links
        • Trigger:Action:Target
      • Anchors (future)
    • Top-level groups (display the name, in brackets the type "Group")
      • Groups are represented as a tree of frames and subgroups.
  • Children nodes can be hidden and shown by a plus located in front of the corresponding parent node
  • Children are arranged by their Z-order, starting from highest (front-most).
  • When the user selects something on the page it is selected in that tree and vice versa (optional).
  • When the user switches to another page/book, the palette is automatically updated.
  • Optional - An element can be dragged up and down changing its Z order (optional).
  • A scroll bar is available in case of long tree structure.

Task result

Source code

Implementation idea

Page structure palette looks like this:

Selected element is the dark gray one and when selected the corresponding frame on the page is selected too. Left mouse button click on the selected element makes it editable and the element can be renamed. After changing the name by pressing enter or by clicking somewhere else the new name is accepted. Renaming of selected element can be achieved by pressing F2 instead of second left mouse button click. While dragging the dragged element can be dropped between two sibling elements or as first or last one. If the element is dropped somewhere else the drag and drop is canceled. His last position is taken by the element which was before it if the element is dragged upwards, and its position is taken by the element which was after it if the element is dragged downwards.

  • We will need a tree palette, so we will implement a TreePalette, based on JTree, which is dynamically changing using Pro lib.
  • The Structure palette will use the current page and it's elements-children and descendants. So it's items will use ElementViews to construct themselves.
  • May be the resource palette will become a tree palette too.

PAGE_STRUCTURE_DISPLAYING_R0
PAGE_STRUCTURE_EDITING_R0

How to demo

  1. Open the page structure palette.
  2. Insert a new text frame and show it in the tree.
  3. Insert a new image frame and show it in the tree.
  4. Drag the text frame to the highest position in the palette list and show that it is displayed over the image frame in the page.
  5. Rename the text frame in the palette and show how its title in the page also changes.

Design

  • TreePalette -> First of all we need TreePalette to implement structured listing (needed for the PageStructurePalette). It is clear that the ListPalette, TreePalette and TablePalette have common structure - header, footer and main component, which is scrollable when the palette becomes too small, or the main component too large.
    • CompoundPalette will be created in org.sophie2.base.layout.model, it will have the header, footer and the main component defined in the ListPalette now.
    • The ListPalette, TablePalette and the new TreePalette will extend the new CompoundPalette. The PanelPalette will not implement it (for now), because a small refactoring is needed to do that (have some hard to change extenders) and we are not sure if it needs that headers and footers, the current extenders don't use such structure at all.
    • The TreePalette will use JTree as a main component.
    • The TreePalette will have items TreePaletteItems and will be generic by it's items.
    • It's clear that the TreePaletteItems and the ListPaletteItems will have some common methods -> the interaction ones, so they will have a common predecessor the InteractableItem.
      • The InteractableItem is abstract class with the following methods with default implementations to do nothing:
        • public void clicked() -> Can be implemented to execute action when the item is clicked.
        • public void doubleClicked() -> Can be implemented to execute action when the item is double clicked.
        • public void selected() -> Can be implemented to execute action when the item is selected.
        • public Transferable draggedOut() -> Implemented if the item can be dragged out.
        • public void keyPressed(KeyEvent e) -> Implemented if action is executed when key is pressed and the item is selected.
      • The ListPaletteItem and TreePaletteItem are similar in this that have the public abstract Object render() method, but for now may be the render method should be devided... Other idea is to have common interface PaletteItem implemented by the InteractableItem and the list palette will have InteractableItems instead of ListItems, but this will lead to small refactoring, that's why this will be leaved if there is enough time. But is good idea to be done some day :)
      • The TreePaletteItem will have the public abstract Object render() method, that is track-able and method public abstract ImmList<I> getChildItems() which will return the it's child item and the implementors will have to write it. 'I' is generic parameter that means I extends TreePaletteItem<I>, in other words the method returns child items of the same kind of which is the item.
    • The data TreePalette will be contained in property public abstract Prop<ImmList<I>> treeItems() that the extendors will override. All the elements of the tree must be contained in that list. The model of the tree will be built over that list using the public abstract ImmList<I> getChildItems() method of the item. Here again 'I' represents I extends TreePaletteItem<I>.
    • DefaultMutableTreeNodes will be used to create the model of the JTree, they will be cached for the items of the tree and will be removed from the cache when an item is deleted, so if the user caches the items correctly the tree will not be rebuilt every time the structure changes. The caching can be done using the object generated from public abstract Object render() of the items, but there is a big chance to have repeating objects generated by public abstract Object render().
    • The tree model will be generated with the algorithm:
      • For every item in the list provided by public abstract Prop<ImmList<I>> treeItems(), get a DefaultMutableTreeNode form the cache or create one if there is no such, then for the children of the item repeat that procedure and add their nodes to the children of the current node. mark all the children items as added to the tree.
      • For every not added to the tree item, add it to the root node of the tree (which is invisible and hidden). This way the items will not need parent items and can be defined easily.
      • Update the tree model, saving the selection and expanded paths.
      • Remove all the entries in the cache (and their children) that are not part of the list with items anymore.
  • PageStructurePalette extends TreePalette.
    • It will have PageStructureItems, that will be constructed by ElementViews, every item will compute it's children using the property ElementView#elementViews()
    • The items will be cached by the ElementViews
    • The public abstract Prop<ImmList<I>> treeItems() list will be constructed by the current BookDocView's RootPageView#mainPartView() property and all it's ElementView children and in it's tree.
    • There could be special PageStructureItem for every leaf ElementView that contain it's properties, links etc...
    • The renaming will be as with the resources palette.
    • Selection will work as in the PagePreviewPalette, but for every element (optional).
  • AllResourcesPalette -> make the resources palette a TreePalette (optional).
  • For now there is a special TreePaletteDemo, that shows updating a custom tree palette (deleting and adding nodes). Will be update to work with selection and renaming nodes.
  • If you think the PageStructurePalette needs special testing there will be, but to bring up the whole Sophie to test things that are tested generally in the demo is meaningless for me.

Implementation

  • Implementation done:
    • Selection form PSP to PWA and from PWA to PSP works.
    • Page extras are shown in PSP when the user chooses to see them.
    • Caching taken out to the tree palette.
    • Renaming elements through the PSP works.
    • Problems :
      • The link items have no resource-target for now, because the LinkActions ad general don't contain targets can be fixed easily as feature.
      • The resource palette is not a tree palette for now, there was some strange bug, with updating the JTree and the resource palette. But there is attached patch to almost working resource palette.
      • Z-oreder change don't work in trunk for now, but when it is fixed the PSP will update.
      • Selection of items is slow as selection viewes in the PWA (normal behavior I think, because it is the same).
    • Branch :

Testing

(Place the testing results here.)

Comments

(Write comments for this or later revisions here.)

Attachments