/*
* Copyright 2015 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.uberfire.client.workbench.panels;
import java.util.Collection;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.user.client.ui.RequiresResize;
import com.google.gwt.user.client.ui.Widget;
import org.uberfire.client.mvp.UberView;
import org.uberfire.client.workbench.WorkbenchLayout;
import org.uberfire.client.workbench.part.WorkbenchPartPresenter;
import org.uberfire.mvp.PlaceRequest;
import org.uberfire.workbench.model.PanelDefinition;
import org.uberfire.workbench.model.PartDefinition;
import org.uberfire.workbench.model.Position;
/**
* Manages the Widget and DOM interaction of a panel. Part of the UberFire MVC system for panels. For a full explanation
* of what a panel is in UberFire, see the class-level documentation for {@link WorkbenchPanelPresenter}.
* <p>
* <h2>View Lifecycle</h2>
* <p>
* UberFire Panel Views are Dependent-scoped beans managed by the Errai IOC container. Views are always created by
* injection into their presenter, which ties their bean lifecycle to that of the presenter: they are created when the
* presenter is created, and they are destroyed when the presenter is destroyed.
* <p>
* This is the lifecycle of a WorkbenchPanelView:
* <ol>
* <li>The view's constructor is invoked by Errai IOC. At this point, it is not yet safe to access injected
* members (they may be uninitialized proxies).
* <li>The view's {@code @PostConstruct} method (if it has one) is invoked by Errai IOC. Safe to access injected members.
* <li>The view's {@link #init(Object)} method is invoked by the presenter. The argument is a reference to the presenter itself.
* <li>The view's widget (obtained from {@link #asWidget()}) is added to the parent panel's widget.
* <li>The view is now in service, and any of its public methods can be called.
* <li>When the panel is no longer needed, Errai IOC is told to destroy the presenter bean. This results in the view bean
* being destroyed too. At this point, the view's {@code @PreDestroy} method is invoked by Errai IOC.
* </ol>
*/
public interface WorkbenchPanelView<P extends WorkbenchPanelPresenter> extends UberView<P>,
RequiresResize {
/**
* Returns this view's presenter.
* @return the presenter that this view is bound to. Will return null if invoked before the presenter calls
* {@link #init(Object)}; afterward, the return value is never null.
*/
P getPresenter();
/**
* Adds the given part view to this panel if this panel does not already contain a view that handles the same
* {@link PlaceRequest} as the given one. If this panel does already contain such a part, the existing one is
* {@link #selectPart(PartDefinition) selected} and the given one is not added.
* @param view the view to add as long as it is not a duplicate. Must not be null.
*/
void addPart(final WorkbenchPartPresenter.View view);
/**
* Nests the given WorkbenchPanelView inside this one at the given position, which must be unoccupied. This is an
* optional feature of WorkbenchPanelView: not all implementations support nested child panels. Additionally,
* different panels support different {@link Position} types. Implementations should document whether or not they
* support child panels, and if so, what types of Positions they understand.
* @param panel specifies the size that should be imposed on the nested view. Must not be null. FIXME: is this
* sensible/correct?
* @param view the panel to nest inside this one. Must not be null.
* @param position specifies which edge of this panel will be shared with the nested panel. Must not be null.
* @throws IllegalStateException if the given position is already occupied by a child panel.
* @throws IllegalArgumentException if the given child position is not understood by this type of panel.
* @throws UnsupportedOperationException if this panel does not support child panels at all.
*/
void addPanel(final PanelDefinition panel,
final WorkbenchPanelView<?> view,
final Position position);
/**
* Removes the view widget associated with the given child from this panel, freeing any resources that were
* allocated by this panel when the child was added.
*/
boolean removePanel(WorkbenchPanelView<?> child);
/**
* Assigns the given title to the given part, if the part belongs to this panel.
* @param part the part whose title to change. Must not be null.
* @param title the new title. Must not be null.
* @param titleDecoration An optional widget to display beside the title. Note that some implementations do not support title
* decorations, and they will ignore this. Null is permitted, and means no decoration.
*/
void changeTitle(final PartDefinition part,
final String title,
final IsWidget titleDecoration);
/**
* Makes the given part visible and focused, if it belongs to this view.
* @param part the part to reveal and give focus to.
* @return true if the part was found, made visible, and given focus. False if not.
*/
boolean selectPart(final PartDefinition part);
/**
* Removes the given part from this view, if it belonged to this view.
* @param part the part to remove.
* @return true if the part was found and removed. False if not.
*/
boolean removePart(final PartDefinition part);
/**
* Informs this view that it has gained or lost keyboard focus. Focused views may respond by updating their style to
* look more prominent than unfocused views.
* @param hasFocus if true, this panel now has focus. If false, this panel does not have focus.
*/
void setFocus(boolean hasFocus);
/**
* Sets the ID of the physical root element of this view. For HTML-based views, this is the {@code id} attribute of
* the view's top-level DOM element. Implementations for other view technologies should map this to whatever the
* underlying widget/component system uses for unique identifiers.
* @param elementId the element ID to set. If null, the ID value will be cleared.
*/
void setElementId(String elementId);
/**
* Returns the widget that defines the boundaries of this panel view for purposes of drag-and-drop.
* @return the widget whose boundaries define the region where workbench parts can be dropped into this panel. For
* simple panel types that do not support child panels, this will typically be the same widget returned by
* {@link #asWidget()}. For fancier panels, this will typically be some child panel within the view's
* internal structure.
* <p>
* If the return value is null, parts will not be droppable on this view.
*/
Widget getPartDropRegion();
/**
* Maximizes this view using {@link WorkbenchLayout#maximize(Widget)}.
*/
void maximize();
/**
* Restores this view to its original unmaximized size and position using {@link WorkbenchLayout#unmaximize(Widget)}.
*/
void unmaximize();
/**
* Returns the parts currently held by the view.
*/
Collection<PartDefinition> getParts();
}