001package gwt.material.design.addins.client.window; 002 003/* 004 * #%L 005 * GwtMaterial 006 * %% 007 * Copyright (C) 2015 - 2016 GwtMaterialDesign 008 * %% 009 * Licensed under the Apache License, Version 2.0 (the "License"); 010 * you may not use this file except in compliance with the License. 011 * You may obtain a copy of the License at 012 * 013 * http://www.apache.org/licenses/LICENSE-2.0 014 * 015 * Unless required by applicable law or agreed to in writing, software 016 * distributed under the License is distributed on an "AS IS" BASIS, 017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 018 * See the License for the specific language governing permissions and 019 * limitations under the License. 020 * #L% 021 */ 022 023 024import com.google.gwt.dom.client.Document; 025import com.google.gwt.dom.client.Style; 026import com.google.gwt.event.dom.client.ClickEvent; 027import com.google.gwt.event.dom.client.ClickHandler; 028import com.google.gwt.event.dom.client.DoubleClickEvent; 029import com.google.gwt.event.dom.client.DoubleClickHandler; 030import com.google.gwt.event.logical.shared.*; 031import com.google.gwt.event.shared.HandlerRegistration; 032import com.google.gwt.user.client.ui.RootPanel; 033import com.google.gwt.user.client.ui.Widget; 034import gwt.material.design.addins.client.MaterialAddins; 035import gwt.material.design.addins.client.dnd.MaterialDnd; 036import gwt.material.design.addins.client.dnd.constants.Restriction; 037import gwt.material.design.client.MaterialDesignBase; 038import gwt.material.design.client.base.MaterialWidget; 039import gwt.material.design.client.base.mixin.ColorsMixin; 040import gwt.material.design.client.base.mixin.ToggleStyleMixin; 041import gwt.material.design.client.constants.IconType; 042import gwt.material.design.client.constants.WavesType; 043import gwt.material.design.client.ui.MaterialIcon; 044import gwt.material.design.client.ui.MaterialLink; 045import gwt.material.design.client.ui.animate.MaterialAnimation; 046 047//@formatter:off 048 049/** 050 * Window is another kind of Modal but it has a header toolbar for maximizing and close the window. Also you can attached a tab component on its content. 051 * 052 * <h3>XML Namespace Declaration</h3> 053 * <pre> 054 * {@code 055 * xmlns:ma='urn:import:gwt.material.design.addins.client' 056 * } 057 * </pre> 058 * 059 * <h3>UiBinder Usage:</h3> 060 * <pre> 061 * {@code 062 * <ma:window.MaterialWindow ui:field="window" /> 063 * } 064 * </pre> 065 * 066 * <h3>UiBinder Usage:</h3> 067 * <pre> 068 * {@code 069 * // Opening a window 070 * window.openWindow(); 071 * 072 * // Closing a window 073 * window.closeWindow(); 074 * } 075 * </pre> 076 * 077 * @author kevzlou7979 078 * @see <a href="http://gwtmaterialdesign.github.io/gwt-material-demo/#window">Material Window</a> 079 */ 080//@formatter:on 081public class MaterialWindow extends MaterialWidget implements HasCloseHandlers<Boolean>, HasOpenHandlers<Boolean>{ 082 083 static { 084 if(MaterialAddins.isDebug()) { 085 MaterialDesignBase.injectCss(MaterialWindowDebugClientBundle.INSTANCE.windowCssDebug()); 086 } else { 087 MaterialDesignBase.injectCss(MaterialWindowClientBundle.INSTANCE.windowCss()); 088 } 089 } 090 091 private MaterialWidget window = new MaterialWidget(Document.get().createDivElement()); 092 private MaterialWidget content = new MaterialWidget(Document.get().createDivElement()); 093 094 // Toolbar elements 095 private MaterialWidget toolbar = new MaterialWidget(Document.get().createDivElement()); 096 private MaterialIcon iconMaximize = new MaterialIcon(IconType.CHECK_BOX_OUTLINE_BLANK); 097 private MaterialIcon iconClose = new MaterialIcon(IconType.CLOSE); 098 private MaterialLink link = new MaterialLink(); 099 private String title = ""; 100 private String toolbarColor; 101 102 private final ColorsMixin<MaterialWidget> toolbarColorMixin = new ColorsMixin<>(toolbar); 103 private final ToggleStyleMixin<MaterialWidget> maximizeMixin = new ToggleStyleMixin<>(window, "maximize"); 104 private final ToggleStyleMixin<MaterialWindow> closeMixin = new ToggleStyleMixin<>(this, "open"); 105 private boolean maximize = true; 106 private boolean open = false; 107 108 private MaterialAnimation openAnimation; 109 private MaterialAnimation closeAnimation; 110 111 112 public MaterialWindow() { 113 super(Document.get().createDivElement(), "window-overlay"); 114 window.setStyleName("window"); 115 content.setStyleName("content"); 116 super.add(window); 117 initWindow(); 118 } 119 120 /** 121 * Builds the toolbar 122 */ 123 protected void initWindow() { 124 toolbar.setStyleName("window-toolbar"); 125 link.setStyleName("window-title"); 126 iconClose.addStyleName("window-action"); 127 iconMaximize.addStyleName("window-action"); 128 iconClose.setCircle(true); 129 iconClose.setWaves(WavesType.DEFAULT); 130 iconMaximize.setCircle(true); 131 iconMaximize.setWaves(WavesType.DEFAULT); 132 toolbar.add(link); 133 toolbar.add(iconClose); 134 toolbar.add(iconMaximize); 135 toolbar.addDomHandler(new DoubleClickHandler() { 136 @Override 137 public void onDoubleClick(DoubleClickEvent event) { 138 toggleMaximize(); 139 Document.get().getDocumentElement().getStyle().setCursor(Style.Cursor.DEFAULT); 140 } 141 }, DoubleClickEvent.getType()); 142 window.add(toolbar); 143 window.add(content); 144 145 // Add handlers to action buttons 146 iconMaximize.addClickHandler(new ClickHandler() { 147 @Override 148 public void onClick(ClickEvent event) { 149 toggleMaximize(); 150 } 151 }); 152 iconClose.addClickHandler(new ClickHandler() { 153 @Override 154 public void onClick(ClickEvent event) { 155 if(open){ 156 openWindow(); 157 open = false; 158 }else{ 159 closeWindow(); 160 open = true; 161 } 162 } 163 }); 164 165 // Add a draggable header 166 MaterialDnd dnd = new MaterialDnd(); 167 dnd.setTarget(window); 168 dnd.setIgnoreFrom(".content, .window-action"); 169 dnd.setRestriction(new Restriction(Restriction.Restrict.PARENT, true, -0.3, 0, 1.1, 1)); 170 } 171 172 protected void toggleMaximize(){ 173 if (maximize) { 174 setMaximize(true); 175 maximize = false; 176 } else { 177 setMaximize(false); 178 maximize = true; 179 } 180 } 181 182 @Override 183 public void add(Widget child) { 184 content.add(child); 185 } 186 187 @Override 188 public String getTitle() { 189 return title; 190 } 191 192 @Override 193 public void setTitle(String title) { 194 this.title = title; 195 link.setText(title); 196 } 197 198 public boolean isMaximize() { 199 return maximizeMixin.isOn(); 200 } 201 202 public void setMaximize(boolean maximize) { 203 maximizeMixin.setOn(maximize); 204 if(maximizeMixin.isOn()){ 205 iconMaximize.setIconType(IconType.FILTER_NONE); 206 }else{ 207 iconMaximize.setIconType(IconType.CHECK_BOX_OUTLINE_BLANK); 208 } 209 } 210 211 /** 212 * Open the window 213 */ 214 public void openWindow() { 215 if (!this.isAttached()) { 216 RootPanel.get().add(this); 217 } 218 this.open = false; 219 OpenEvent.fire(this, true); 220 if (openAnimation != null) { 221 openAnimation.animate(window); 222 } 223 closeMixin.setOn(true); 224 } 225 226 /** 227 * Close the window 228 */ 229 public void closeWindow() { 230 this.open = true; 231 CloseEvent.fire(this, false); 232 if (closeAnimation == null) { 233 closeMixin.setOn(false); 234 } else { 235 closeAnimation.animate(window, new Runnable() { 236 @Override 237 public void run() { 238 closeMixin.setOn(false); 239 } 240 }); 241 } 242 } 243 244 public String getToolbarColor() { 245 return toolbarColor; 246 } 247 248 public void setToolbarColor(String toolbarColor) { 249 this.toolbarColor = toolbarColor; 250 toolbarColorMixin.setBackgroundColor(toolbarColor); 251 } 252 253 public void setOpenAnimation(final MaterialAnimation openAnimation) { 254 this.openAnimation = openAnimation; 255 } 256 257 public void setCloseAnimation(final MaterialAnimation closeAnimation) { 258 this.closeAnimation = closeAnimation; 259 } 260 261 @Override 262 public HandlerRegistration addCloseHandler(final CloseHandler<Boolean> handler) { 263 return addHandler(new CloseHandler<Boolean>() { 264 @Override 265 public void onClose(CloseEvent<Boolean> event) { 266 if(isEnabled()){ 267 handler.onClose(event); 268 } 269 } 270 }, CloseEvent.getType()); 271 } 272 273 @Override 274 public HandlerRegistration addOpenHandler(final OpenHandler<Boolean> handler) { 275 return addHandler(new OpenHandler<Boolean>() { 276 @Override 277 public void onOpen(OpenEvent<Boolean> event) { 278 if(isEnabled()){ 279 handler.onOpen(event); 280 } 281 } 282 }, OpenEvent.getType()); 283 } 284 285 @Override 286 public void setWidth(String width) { 287 window.setWidth(width); 288 } 289 290 @Override 291 public void setHeight(String height) { 292 window.setHeight(height); 293 } 294 295 @Override 296 public void setBackgroundColor(String bgColor) { 297 window.setBackgroundColor(bgColor); 298 } 299 300 public boolean isOpen() { 301 return open; 302 } 303}