1 /* 2 * PanmirrorToolbar.java 3 * 4 * Copyright (C) 2021 by RStudio, PBC 5 * 6 * Unless you have received this program directly from RStudio pursuant 7 * to the terms of a commercial license agreement with RStudio, then 8 * this program is licensed to you under the terms of version 3 of the 9 * GNU Affero General Public License. This program is distributed WITHOUT 10 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT, 11 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the 12 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details. 13 * 14 */ 15 16 package org.rstudio.studio.client.panmirror.command; 17 18 import java.util.ArrayList; 19 20 import org.rstudio.core.client.widget.HasFindReplace; 21 import org.rstudio.core.client.widget.SecondaryToolbar; 22 import org.rstudio.core.client.widget.ToolbarButton; 23 import org.rstudio.core.client.widget.ToolbarMenuButton; 24 import org.rstudio.studio.client.workbench.views.source.editors.text.findreplace.FindReplaceBar; 25 26 import com.google.gwt.dom.client.Style.Unit; 27 import com.google.gwt.event.dom.client.ClickEvent; 28 import com.google.gwt.event.dom.client.ClickHandler; 29 import com.google.gwt.user.client.ui.HorizontalPanel; 30 import com.google.gwt.user.client.ui.RequiresResize; 31 import com.google.gwt.user.client.ui.Widget; 32 33 34 public class PanmirrorToolbar extends SecondaryToolbar implements RequiresResize 35 { PanmirrorToolbar()36 public PanmirrorToolbar() 37 { 38 super(false, "Panmirror Editor Toolbar"); 39 getElement().getStyle().setHeight(getHeight(), Unit.PX); 40 } 41 42 @Override getHeight()43 public int getHeight() 44 { 45 return 23; 46 } 47 init(PanmirrorToolbarCommands commands, PanmirrorMenus menus, HasFindReplace findReplace)48 public void init(PanmirrorToolbarCommands commands, PanmirrorMenus menus, HasFindReplace findReplace) 49 { 50 51 commands_ = commands; 52 menus_ = menus; 53 commandObjects_.clear(); 54 removeAllWidgets(); 55 56 PanmirrorToolbarRadioMenu blockMenu = createBlockMenu(); 57 addLeftTextMenu(addRadioMenu(blockMenu)); 58 59 addLeftSeparator(); 60 61 formatWidgets_ = addWidgetGroup( 62 addLeftButton(PanmirrorCommands.Strong), 63 addLeftButton(PanmirrorCommands.Em), 64 addLeftButton(PanmirrorCommands.Underline), 65 addLeftButton(PanmirrorCommands.Code), 66 addLeftSeparator(), 67 addLeftButton(PanmirrorCommands.ClearFormatting), 68 addLeftSeparator() 69 ); 70 71 blockWidgets_ = addWidgetGroup( 72 addLeftButton(PanmirrorCommands.BulletList), 73 addLeftButton(PanmirrorCommands.OrderedList), 74 addLeftButton(PanmirrorCommands.Blockquote), 75 addLeftSeparator() 76 ); 77 78 insertWidgets_ = addWidgetGroup( 79 addLeftButton(PanmirrorCommands.Link), 80 addLeftButton(PanmirrorCommands.Citation), 81 addLeftSeparator(), 82 addLeftButton(PanmirrorCommands.Image), 83 addLeftSeparator() 84 ); 85 86 87 PanmirrorToolbarMenu formatMenu = new PanmirrorToolbarMenu(commands_, menus_.format); 88 addLeftTextMenu(new ToolbarMenuButton("Format", "Format", null, formatMenu, false)); 89 90 addLeftSeparator(); 91 92 PanmirrorToolbarMenu insertMenu = new PanmirrorToolbarMenu(commands_, menus_.insert); 93 addLeftTextMenu(new ToolbarMenuButton("Insert", "Insert", null, insertMenu, false)); 94 95 if (haveAnyOf(PanmirrorCommands.TableInsertTable)) 96 { 97 addLeftSeparator(); 98 PanmirrorToolbarMenu tableMenu = new PanmirrorToolbarMenu(commands_, menus_.table); 99 addLeftTextMenu(new ToolbarMenuButton("Table", "Table", null, tableMenu, false)); 100 } 101 102 if (findReplace != null) 103 { 104 addLeftSeparator(); 105 findReplaceButton_ = new ToolbarButton( 106 ToolbarButton.NoText, 107 "Find/Replace", 108 FindReplaceBar.getFindIcon(), 109 new ClickHandler() { 110 public void onClick(ClickEvent event) 111 { 112 boolean show = !findReplace.isFindReplaceShowing(); 113 findReplace.showFindReplace(show); 114 } 115 }); 116 addLeftWidget(findReplaceButton_); 117 } 118 } 119 120 sync(boolean images)121 public void sync(boolean images) 122 { 123 commandObjects_.forEach((object) -> object.sync(images)); 124 invalidateSeparators(); 125 onResize(); 126 } 127 setFindReplaceLatched(boolean latched)128 public void setFindReplaceLatched(boolean latched) 129 { 130 if (findReplaceButton_ != null) 131 { 132 findReplaceButton_.setLeftImage(latched ? 133 FindReplaceBar.getFindLatchedIcon() : 134 FindReplaceBar.getFindIcon() 135 ); 136 } 137 } 138 139 @Override addLeftSeparator()140 public Widget addLeftSeparator() 141 { 142 Widget separator = super.addLeftSeparator(); 143 separator.addStyleName(RES.styles().toolbarSeparator()); 144 return separator; 145 } 146 147 @Override onResize()148 public void onResize() 149 { 150 int width = getOffsetWidth(); 151 if (width == 0) 152 return; 153 154 formatWidgets_.setVisible(width > 475); 155 blockWidgets_.setVisible(width > 555); 156 insertWidgets_.setVisible(width > 610); 157 158 } 159 160 createBlockMenu()161 private PanmirrorToolbarRadioMenu createBlockMenu() 162 { 163 PanmirrorToolbarRadioMenu blockMenu = new PanmirrorToolbarRadioMenu("Normal", "Block Format", commands_); 164 blockMenu.addCommand(PanmirrorCommands.Paragraph); 165 blockMenu.addSeparator(); 166 blockMenu.addCommand(PanmirrorCommands.Heading1); 167 blockMenu.addCommand(PanmirrorCommands.Heading2); 168 blockMenu.addCommand(PanmirrorCommands.Heading3); 169 blockMenu.addCommand(PanmirrorCommands.Heading4); 170 blockMenu.addCommand(PanmirrorCommands.Heading5); 171 blockMenu.addCommand(PanmirrorCommands.Heading6); 172 blockMenu.addSeparator(); 173 blockMenu.addCommand(PanmirrorCommands.CodeBlock); 174 return blockMenu; 175 } 176 177 178 haveAnyOf(String...ids)179 private boolean haveAnyOf(String...ids) 180 { 181 for (String id : ids) 182 { 183 if (commands_.get(id).isVisible()) 184 return true; 185 } 186 return false; 187 } 188 189 addLeftButton(String id)190 private Widget addLeftButton(String id) 191 { 192 return addLeftWidget(addButton(id)); 193 } 194 addLeftTextMenu(ToolbarMenuButton menuButton)195 private void addLeftTextMenu(ToolbarMenuButton menuButton) 196 { 197 addLeftWidget(menuButton); 198 menuButton.addStyleName(RES.styles().toolbarTextMenuButton()); 199 } 200 addRadioMenu(PanmirrorToolbarRadioMenu menu)201 private PanmirrorToolbarRadioMenu addRadioMenu(PanmirrorToolbarRadioMenu menu) 202 { 203 commandObjects_.add(menu); 204 return menu; 205 } 206 addButton(String id)207 private PanmirrorCommandButton addButton(String id) 208 { 209 PanmirrorCommandButton button = new PanmirrorCommandButton(commands_.get(id)); 210 commandObjects_.add(button); 211 return button; 212 } 213 addWidgetGroup(Widget...widgets)214 private HorizontalPanel addWidgetGroup(Widget...widgets) 215 { 216 HorizontalPanel group = new HorizontalPanel(); 217 for (Widget widget : widgets) 218 group.add(widget); 219 addLeftWidget(group); 220 return group; 221 } 222 223 private static final PanmirrorToolbarResources RES = PanmirrorToolbarResources.INSTANCE; 224 225 private HorizontalPanel formatWidgets_ = null; 226 private HorizontalPanel insertWidgets_ = null; 227 private HorizontalPanel blockWidgets_ = null; 228 229 private ToolbarButton findReplaceButton_ = null; 230 231 private PanmirrorToolbarCommands commands_ = null; 232 private PanmirrorMenus menus_ = null; 233 private ArrayList<PanmirrorCommandUIObject> commandObjects_ = new ArrayList<>(); 234 } 235