1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.ui.vaadin.gwt.client.tabsheet.widget;
35
36 import info.magnolia.ui.vaadin.gwt.client.jquerywrapper.JQueryCallback;
37 import info.magnolia.ui.vaadin.gwt.client.jquerywrapper.JQueryWrapper;
38 import info.magnolia.ui.vaadin.gwt.client.magnoliashell.viewport.animation.FadeAnimation;
39 import info.magnolia.ui.vaadin.gwt.client.magnoliashell.viewport.animation.JQueryAnimation;
40 import info.magnolia.ui.vaadin.gwt.client.magnoliashell.viewport.widget.AppPreloader;
41 import info.magnolia.ui.vaadin.gwt.client.tabsheet.event.ActiveTabChangedEvent;
42 import info.magnolia.ui.vaadin.gwt.client.tabsheet.event.TabSetChangedEvent;
43 import info.magnolia.ui.vaadin.gwt.client.tabsheet.event.TabSetChangedEvent.Handler;
44 import info.magnolia.ui.vaadin.gwt.client.tabsheet.tab.widget.MagnoliaTabWidget;
45 import info.magnolia.ui.vaadin.gwt.client.tabsheet.util.CollectionUtil;
46
47 import java.util.Iterator;
48 import java.util.LinkedList;
49 import java.util.List;
50
51 import com.google.gwt.core.client.Scheduler;
52 import com.google.gwt.core.client.Scheduler.ScheduledCommand;
53 import com.google.gwt.dom.client.Style;
54 import com.google.gwt.dom.client.Style.Display;
55 import com.google.gwt.dom.client.Style.Position;
56 import com.google.gwt.dom.client.Style.Unit;
57 import com.google.gwt.event.shared.HandlerRegistration;
58 import com.google.gwt.user.client.DOM;
59 import com.google.gwt.user.client.Element;
60 import com.google.gwt.user.client.Timer;
61 import com.google.gwt.user.client.ui.FlowPanel;
62 import com.google.gwt.user.client.ui.ScrollPanel;
63 import com.google.gwt.user.client.ui.Widget;
64 import com.google.web.bindery.event.shared.EventBus;
65
66
67
68
69
70
71
72 public class MagnoliaTabSheetViewImpl extends FlowPanel implements MagnoliaTabSheetView {
73
74 private static final String CLASSNAME_CONTENT_SHOW_ALL = "show-all";
75
76 private final List<MagnoliaTabWidget> tabs = new LinkedList<MagnoliaTabWidget>();
77
78 private final ScrollPanel scroller = new ScrollPanel();
79
80 private final FlowPanel tabPanel = new FlowPanel();
81
82 private final TabBarWidget tabBar;
83
84 private MagnoliaTabWidget activeTab = null;
85
86 private boolean showingAllTabs;
87
88 private AppPreloader preloader = new AppPreloader();
89
90 private FadeAnimation preloaderFadeOut = new FadeAnimation(0d, true);
91
92 private Element logo;
93
94 private ScheduledCommand removePreloaderCommand;
95
96 public MagnoliaTabSheetViewImpl(EventBus eventBus) {
97 super();
98 this.tabBar = new TabBarWidget(eventBus);
99 this.logo = DOM.createDiv();
100 addStyleName("v-shell-tabsheet");
101 scroller.addStyleName("v-shell-tabsheet-scroller");
102 tabPanel.addStyleName("v-shell-tabsheet-tab-wrapper");
103 getElement().appendChild(logo);
104 add(tabBar);
105 add(scroller);
106 scroller.setWidget(tabPanel);
107 scroller.getElement().getStyle().setPosition(Position.ABSOLUTE);
108 this.preloaderFadeOut.addCallback(new JQueryCallback() {
109 @Override
110 public void execute(JQueryWrapper query) {
111 doRemovePreloader();
112 }
113 });
114 }
115
116 @Override
117 public TabBarWidget getTabContainer() {
118 return tabBar;
119 }
120
121
122 @Override
123 public void removeTab(MagnoliaTabWidget tabToOrphan) {
124 if (activeTab == tabToOrphan) {
125 final MagnoliaTabWidget nextTab = CollectionUtil.getNext(getTabs(), tabToOrphan);
126 if (nextTab != null) {
127 setActiveTab(nextTab);
128 }
129 }
130 getTabs().remove(tabToOrphan);
131 tabPanel.remove(tabToOrphan);
132 }
133
134 @Override
135 public void setActiveTab(final MagnoliaTabWidget tab) {
136 this.activeTab = tab;
137
138 showAllTabContents(false);
139 tab.getElement().getStyle().clearDisplay();
140 animateHeightChange(tab);
141 }
142
143 private static final int HEIGHT_CHANGE_ANIMATION_DURATION = 200;
144
145 private void animateHeightChange(MagnoliaTabWidget newActiveTab) {
146 final Style tabPanelStyle = tabPanel.getElement().getStyle();
147 int offsetTabHeight = tabPanel.getOffsetHeight();
148 tabPanelStyle.clearHeight();
149 int newHeight = newActiveTab.getOffsetHeight();
150 final String heightPropertyCC = offsetTabHeight < newHeight ? "maxHeight" : "minHeight";
151 final String heightProperty = offsetTabHeight < newHeight ? "max-height" : "min-height";
152
153 final JQueryAnimation animation = new JQueryAnimation();
154 tabPanelStyle.setProperty(heightPropertyCC, offsetTabHeight + "px");
155 animation.setProperty(heightProperty, newHeight);
156 tabPanelStyle.setOverflow(Style.Overflow.HIDDEN);
157 animation.addCallback(new JQueryCallback() {
158 @Override
159 public void execute(JQueryWrapper query) {
160 tabPanelStyle.clearOverflow();
161 tabPanelStyle.clearProperty(heightPropertyCC);
162 }
163 });
164 animation.run(HEIGHT_CHANGE_ANIMATION_DURATION, tabPanel.getElement());
165 }
166
167 @Override
168 public MagnoliaTabWidget getActiveTab() {
169 return activeTab;
170 }
171
172
173 @Override
174 public List<MagnoliaTabWidget> getTabs() {
175 return tabs;
176 }
177
178 @Override
179 public void showAllTabContents(boolean visible) {
180 for (MagnoliaTabWidget tab : getTabs()) {
181
182 if (visible) {
183 tab.getElement().getStyle().clearDisplay();
184 tab.getElement().getStyle().clearHeight();
185 } else {
186 tab.getElement().getStyle().setDisplay(Display.NONE);
187 tab.getElement().getStyle().setHeight(100, Unit.PCT);
188 }
189 }
190 if (visible) {
191 addStyleName(CLASSNAME_CONTENT_SHOW_ALL);
192 } else {
193 removeStyleName(CLASSNAME_CONTENT_SHOW_ALL);
194 }
195 showingAllTabs = visible;
196 }
197
198 @Override
199 public boolean isShowingAllTabs() {
200 return showingAllTabs;
201 }
202
203 @Override
204 public void updateTab(MagnoliaTabWidget tab) {
205 if (!tabs.contains(tab)) {
206 showPreloader();
207 getTabs().add(tab);
208 tabPanel.add(tab);
209 tabBar.addTabLabel(tab.getLabel());
210 fireEvent(new TabSetChangedEvent(this));
211 }
212 }
213
214 @Override
215 protected void onLoad() {
216 super.onLoad();
217 fireEvent(new TabSetChangedEvent(this));
218 }
219
220 @Override
221 public HandlerRegistration addTabSetChangedHandler(Handler handler) {
222 return addHandler(handler, TabSetChangedEvent.TYPE);
223 }
224
225 @Override
226 public HandlerRegistration addActiveTabChangedHandler(ActiveTabChangedEvent.Handler handler) {
227 return addHandler(handler, ActiveTabChangedEvent.TYPE);
228 }
229
230 @Override
231 public void setLogo(String logo, String logoBgColor) {
232 this.logo.addClassName("v-shell-tabsheet-logo");
233 this.logo.addClassName(logo);
234 this.logo.getStyle().setBackgroundColor(logoBgColor);
235 }
236
237 @Override
238 public void setMaxHeight(int height) {
239 int tabBarHeight = getOffsetHeight() - scroller.getOffsetHeight();
240 height -= tabBarHeight;
241 final Style scrollerStyle = scroller.getElement().getStyle();;
242 scrollerStyle.setPosition(Position.ABSOLUTE);
243 scrollerStyle.setOverflow(Style.Overflow.AUTO);
244 scrollerStyle.setProperty("zoom", "1");
245 scrollerStyle.setProperty("maxHeight", height + "px");
246 }
247
248 Timer preloaderRemoverTimer = new Timer() {
249 @Override
250 public void run() {
251 doRemovePreloader();
252 }
253 };
254
255 @Override
256 public void showPreloader() {
257 preloaderFadeOut.cancel();
258 preloaderRemoverTimer.cancel();
259 if (tabPanel != preloader.getParent()) {
260 preloader.getElement().getStyle().setTop(0, Unit.PX);
261 preloader.getElement().getStyle().setZIndex(10000);
262 tabPanel.add(preloader);
263 }
264 }
265
266 @Override
267 public void removePreloader() {
268 if (removePreloaderCommand == null) {
269 removePreloaderCommand = new ScheduledCommand() {
270 @Override
271 public void execute() {
272 if (tabPanel == preloader.getParent()) {
273 preloaderFadeOut.run(500, preloader.getElement());
274 }
275 removePreloaderCommand = null;
276 }
277 };
278 Scheduler.get().scheduleDeferred(removePreloaderCommand);
279 preloaderRemoverTimer.schedule(1000);
280 }
281 }
282
283 @Override
284 public void clearTabs() {
285 final Iterator<Widget> it = tabPanel.iterator();
286 while (it.hasNext()) {
287 final Widget w = it.next();
288 if (w == getActiveTab()) {
289 tabPanel.setHeight(w.getOffsetHeight() + "px");
290 }
291 if (w != preloader) {
292 w.getElement().getStyle().setDisplay(Display.NONE);
293 }
294 }
295 }
296
297 private void doRemovePreloader() {
298 tabPanel.remove(preloader);
299 }
300 }