001package org.gwtbootstrap3.client.ui.base.mixin;
002
003/*
004 * #%L
005 * GwtBootstrap3
006 * %%
007 * Copyright (C) 2016 GwtBootstrap3
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
023import com.google.gwt.core.client.Scheduler;
024import com.google.gwt.user.client.ui.HasText;
025
026import org.gwtbootstrap3.client.ui.Badge;
027import org.gwtbootstrap3.client.ui.Icon;
028import org.gwtbootstrap3.client.ui.base.ComplexWidget;
029import org.gwtbootstrap3.client.ui.base.HasBadge;
030import org.gwtbootstrap3.client.ui.base.HasIcon;
031import org.gwtbootstrap3.client.ui.base.HasIconPosition;
032import org.gwtbootstrap3.client.ui.constants.BadgePosition;
033import org.gwtbootstrap3.client.ui.constants.IconFlip;
034import org.gwtbootstrap3.client.ui.constants.IconPosition;
035import org.gwtbootstrap3.client.ui.constants.IconRotate;
036import org.gwtbootstrap3.client.ui.constants.IconSize;
037import org.gwtbootstrap3.client.ui.constants.IconType;
038import org.gwtbootstrap3.client.ui.html.Text;
039
040/**
041 * Mixin for Widgets that have text, an optional icon, and an optional badge
042 *
043 * @author Sven Jacobs
044 * @author Drew Spencer
045 */
046public class IconTextMixin<T extends ComplexWidget & HasText & HasIcon & HasIconPosition & HasBadge> implements
047        HasText, HasIcon, HasIconPosition, HasBadge {
048
049    private final T widget;
050    private final Text text = new Text();
051    private final Text separator = new Text(" ");
052    private final Text badgeSeparator = new Text(" ");
053    private Icon icon;
054    private IconType iconType;
055    private IconPosition iconPosition = IconPosition.LEFT;
056    private IconSize iconSize = IconSize.NONE;
057    private IconFlip iconFlip = IconFlip.NONE;
058    private IconRotate iconRotate = IconRotate.NONE;
059    private boolean iconInverse = false;
060    private boolean iconSpin = false;
061    private boolean iconPulse = false;
062    private boolean iconBordered = false;
063    private boolean iconFixedWidth = false;
064    private Badge badge = new Badge();
065    private BadgePosition badgePosition = BadgePosition.RIGHT;
066
067    public IconTextMixin(final T widget) {
068        this.widget = widget;
069    }
070
071    public void addTextWidgetToParent() {
072        widget.add(text);
073    }
074
075    @Override
076    public void setText(final String text) {
077        this.text.setText(text);
078        render();
079    }
080
081    @Override
082    public String getText() {
083        return text.getText();
084    }
085
086    @Override
087    public void setIcon(final IconType iconType) {
088        this.iconType = iconType;
089        render();
090    }
091
092    @Override
093    public IconType getIcon() {
094        return icon == null ? null : icon.getType();
095    }
096
097    @Override
098    public void setIconPosition(final IconPosition iconPosition) {
099        this.iconPosition = iconPosition;
100        render();
101    }
102
103    @Override
104    public IconPosition getIconPosition() {
105        return iconPosition;
106    }
107
108    @Override
109    public void setIconSize(final IconSize iconSize) {
110        this.iconSize = iconSize;
111        render();
112    }
113
114    @Override
115    public IconSize getIconSize() {
116        return iconSize;
117    }
118
119    @Override
120    public void setIconFlip(final IconFlip iconFlip) {
121        this.iconFlip = iconFlip;
122        render();
123    }
124
125    @Override
126    public IconFlip getIconFlip() {
127        return iconFlip;
128    }
129
130    @Override
131    public void setIconRotate(final IconRotate iconRotate) {
132        this.iconRotate = iconRotate;
133        render();
134    }
135
136    @Override
137    public IconRotate getIconRotate() {
138        return iconRotate;
139    }
140
141    @Override
142    public void setIconBordered(final boolean iconBordered) {
143        this.iconBordered = iconBordered;
144        render();
145    }
146
147    @Override
148    public boolean isIconBordered() {
149        return iconBordered;
150    }
151
152    @Override
153    public void setIconInverse(final boolean iconInverse) {
154        this.iconInverse = iconInverse;
155        render();
156    }
157
158    @Override
159    public boolean isIconInverse() {
160        return iconInverse;
161    }
162
163    @Override
164    public void setIconSpin(final boolean iconSpin) {
165        this.iconSpin = iconSpin;
166        render();
167    }
168
169    @Override
170    public boolean isIconSpin() {
171        return iconSpin;
172    }
173
174    @Override
175    public void setIconPulse(boolean iconPulse) {
176        this.iconPulse = iconPulse;
177        render();
178    }
179
180    @Override
181    public boolean isIconPulse() {
182        return iconPulse;
183    }
184
185    @Override
186    public void setIconFixedWidth(final boolean iconFixedWidth) {
187        this.iconFixedWidth = iconFixedWidth;
188        render();
189    }
190
191    @Override
192    public boolean isIconFixedWidth() {
193        return iconFixedWidth;
194    }
195
196    @Override
197    public void setBadgeText(String badgeText) {
198        badge.setText(badgeText);
199        render();
200    }
201
202    @Override
203    public String getBadgeText() {
204        return badge.getText();
205    }
206
207    @Override
208    public void setBadgePosition(final BadgePosition badgePosition) {
209        this.badgePosition = badgePosition;
210        render();
211    }
212
213    @Override
214    public BadgePosition getBadgePosition() {
215        return badgePosition;
216    }
217
218    private void render() {
219        // We defer to make sure the elements are available to manipulate their positions
220        Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() {
221            @Override
222            public void execute() {
223
224                if (text.isAttached()) {
225                    text.removeFromParent();
226                }
227
228                if (separator.isAttached()) {
229                    separator.removeFromParent();
230                }
231
232                if (badgeSeparator.isAttached()) {
233                    badgeSeparator.removeFromParent();
234                }
235
236                if (badge.isAttached()) {
237                    badge.removeFromParent();
238                }
239
240                if (icon != null) {
241                    icon.removeFromParent();
242                    icon = null;
243                }
244
245                if (iconType != null) {
246                    icon = new Icon();
247                    icon.setType(iconType);
248                    icon.setSize(iconSize);
249                    icon.setFlip(iconFlip);
250                    icon.setRotate(iconRotate);
251                    icon.setSpin(iconSpin);
252                    icon.setPulse(iconPulse);
253                    icon.setBorder(iconBordered);
254                    icon.setFixedWidth(iconFixedWidth);
255                    icon.setInverse(iconInverse);
256                }
257
258                // Since we are dealing with Icon/Text, we can insert them at the right position
259                // Helps on widgets like ButtonDropDown, where it has a caret added
260                int position = 0;
261
262                if (badge.getText() != null && badge.getText().length() > 0 && badgePosition == BadgePosition.LEFT) {
263                    widget.insert(badge, position++);
264                    widget.insert(badgeSeparator, position++);
265                }
266
267                if (icon != null && iconPosition == IconPosition.LEFT) {
268                    widget.insert(icon, position++);
269                    widget.insert(separator, position++);
270                }
271
272                if (text.getText() != null && text.getText().length() > 0) {
273                    widget.insert(text, position++);
274                }
275
276                if (icon != null && iconPosition == IconPosition.RIGHT) {
277                    widget.insert(separator, position++);
278                    widget.insert(icon, position++);
279                }
280
281                if (badge.getText() != null && badge.getText().length() > 0 && badgePosition == BadgePosition.RIGHT) {
282                    widget.insert(badgeSeparator, position++);
283                    widget.insert(badge, position++);
284                }
285
286                // hack to remove css spacing in Pills
287                badge.setMarginLeft(0);
288                badge.setMarginRight(0);
289
290            }
291        });
292    }
293}