<commit_before>/*
 * ToolbarButton.java
 *
 * Copyright (C) 2009-12 by RStudio, Inc.
 *
 * Unless you have received this program directly from RStudio pursuant
 * to the terms of a commercial license agreement with RStudio, then
 * this program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */
package org.rstudio.core.client.widget;

import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.*;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.event.dom.client.*;
import com.google.gwt.event.logical.shared.CloseEvent;
import com.google.gwt.event.logical.shared.CloseHandler;
import com.google.gwt.event.shared.*;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.PopupPanel.PositionCallback;
import com.google.gwt.user.client.ui.Widget;
import org.rstudio.core.client.StringUtil;
import org.rstudio.core.client.command.ImageResourceProvider;
import org.rstudio.core.client.command.SimpleImageResourceProvider;
import org.rstudio.core.client.theme.res.ThemeResources;
import org.rstudio.core.client.theme.res.ThemeStyles;


public class ToolbarButton extends FocusWidget
{
   private class SimpleHasHandlers extends HandlerManager implements HasHandlers
   {
      private SimpleHasHandlers()
      {
         super(null);
      }
   }
   
   public <T extends EventHandler> ToolbarButton(
                                      String text, 
                                      ImageResource leftImg, 
                                      final HandlerManager eventBus,
                                      final GwtEvent<? extends T> targetEvent)
   {
      this(text, leftImg, new ClickHandler() {
         public void onClick(ClickEvent event)
         {
           eventBus.fireEvent(targetEvent);
         }
      });
   }
   
   public <T extends EventHandler> ToolbarButton(
                                       ImageResource img, 
                                       final HandlerManager eventBus,
                                       final GwtEvent<? extends T> targetEvent)
   {
      this(null, img, eventBus, targetEvent);
   }
   
   public ToolbarButton(String text, 
                        ImageResourceProvider leftImageProvider,
                        ClickHandler clickHandler)
   {
      this(text, leftImageProvider, null, clickHandler);
   }
   
   public ToolbarButton(String text, 
                        ImageResource leftImage,
                        ClickHandler clickHandler)
   {
      this(text, new SimpleImageResourceProvider(leftImage), clickHandler);
   }
   
   public ToolbarButton(ImageResource image,
                        ClickHandler clickHandler)
   {
      this(null, image, clickHandler);
   }
   
   public ToolbarButton(ToolbarPopupMenu menu, boolean rightAlignMenu)
   {
      this((String)null, 
           ThemeResources.INSTANCE.menuDownArrow(), 
           (ImageResource) null,
           (ClickHandler) null);
      
      addMenuHandlers(menu, rightAlignMenu);
      
      addStyleName(styles_.toolbarButtonMenu());
      addStyleName(styles_.toolbarButtonMenuOnly());
   }
      
   public ToolbarButton(String text, 
                        ImageResource leftImage,
                        ToolbarPopupMenu menu)
   {
      this(text, leftImage, menu, false);
   }
   
   public ToolbarButton(String text,
                        ImageResourceProvider leftImage,
                        ToolbarPopupMenu menu)
   {
      this(text, leftImage, menu, false);
   }
    
   public ToolbarButton(String text, 
                        ImageResource leftImage,
                        ToolbarPopupMenu menu,
                        boolean rightAlignMenu)
   {
      this(text,
           new SimpleImageResourceProvider(leftImage),
           menu, 
           rightAlignMenu);
   }

   public ToolbarButton(String text, 
                        ImageResourceProvider leftImage,
                        ToolbarPopupMenu menu,
                        boolean rightAlignMenu)
   {
      this(text, leftImage, ThemeResources.INSTANCE.menuDownArrow(), null);

      addMenuHandlers(menu, rightAlignMenu);
      
      addStyleName(styles_.toolbarButtonMenu());
   }
   
   
   private void addMenuHandlers(final ToolbarPopupMenu popupMenu, 
                                final boolean rightAlign)
   {
      menu_ = popupMenu;
      /*
       * We want clicks on this button to toggle the visibility of the menu,
       * as well as having the menu auto-hide itself as it normally does.
       * It's necessary to manually track the visibility (menuShowing) because
       * in the case where the menu is showing, clicking on this button first
       * causes the menu to auto-hide and then our mouseDown handler is called
       * (so we can't rely on menu.isShowing(), it'll always be false by the
       * time you get into the mousedown handler).
       */

      final boolean[] menuShowing = new boolean[1];

      addMouseDownHandler(new MouseDownHandler()
      {
         public void onMouseDown(MouseDownEvent event)
         {
            event.preventDefault();
            event.stopPropagation();
            addStyleName(styles_.toolbarButtonPushed());
            // Some menus are rebuilt on every invocation. Ask the menu for 
            // the most up-to-date version before proceeding.
            popupMenu.getDynamicPopupMenu(
               new ToolbarPopupMenu.DynamicPopupMenuCallback()
            {
               @Override
               public void onPopupMenu(final ToolbarPopupMenu menu)
               {
                  if (menuShowing[0])
                     menu.hide();
                  else
                  {
                     if (rightAlign)
                     {
                        menu.setPopupPositionAndShow(new PositionCallback() 
                        {
                           @Override
                           public void setPosition(int offsetWidth, 
                                                   int offsetHeight)
                           {
                              menu.setPopupPosition(
                                 (rightImageWidget_ != null ?
                                       rightImageWidget_.getAbsoluteLeft() :
                                       leftImageWidget_.getAbsoluteLeft())
                                 + 20 - offsetWidth, 
                                 ToolbarButton.this.getAbsoluteTop() +
                                 ToolbarButton.this.getOffsetHeight());
                           } 
                        });
                     }
                     else
                     {
                        menu.showRelativeTo(ToolbarButton.this);
                     }
                     menuShowing[0] = true;
                  }
               }
            });
         }
      });<commit_msg>ensure double-clicking on a toolbar button removes 'pushed' state<commit_after>/*
 * ToolbarButton.java
 *
 * Copyright (C) 2009-12 by RStudio, Inc.
 *
 * Unless you have received this program directly from RStudio pursuant
 * to the terms of a commercial license agreement with RStudio, then
 * this program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */
package org.rstudio.core.client.widget;

import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.*;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.event.dom.client.*;
import com.google.gwt.event.logical.shared.CloseEvent;
import com.google.gwt.event.logical.shared.CloseHandler;
import com.google.gwt.event.shared.*;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.PopupPanel.PositionCallback;
import com.google.gwt.user.client.ui.Widget;
import org.rstudio.core.client.StringUtil;
import org.rstudio.core.client.command.ImageResourceProvider;
import org.rstudio.core.client.command.SimpleImageResourceProvider;
import org.rstudio.core.client.theme.res.ThemeResources;
import org.rstudio.core.client.theme.res.ThemeStyles;


public class ToolbarButton extends FocusWidget
{
   private class SimpleHasHandlers extends HandlerManager implements HasHandlers
   {
      private SimpleHasHandlers()
      {
         super(null);
      }
   }
   
   public <T extends EventHandler> ToolbarButton(
                                      String text, 
                                      ImageResource leftImg, 
                                      final HandlerManager eventBus,
                                      final GwtEvent<? extends T> targetEvent)
   {
      this(text, leftImg, new ClickHandler() {
         public void onClick(ClickEvent event)
         {
           eventBus.fireEvent(targetEvent);
         }
      });
   }
   
   public <T extends EventHandler> ToolbarButton(
                                       ImageResource img, 
                                       final HandlerManager eventBus,
                                       final GwtEvent<? extends T> targetEvent)
   {
      this(null, img, eventBus, targetEvent);
   }
   
   public ToolbarButton(String text, 
                        ImageResourceProvider leftImageProvider,
                        ClickHandler clickHandler)
   {
      this(text, leftImageProvider, null, clickHandler);
   }
   
   public ToolbarButton(String text, 
                        ImageResource leftImage,
                        ClickHandler clickHandler)
   {
      this(text, new SimpleImageResourceProvider(leftImage), clickHandler);
   }
   
   public ToolbarButton(ImageResource image,
                        ClickHandler clickHandler)
   {
      this(null, image, clickHandler);
   }
   
   public ToolbarButton(ToolbarPopupMenu menu, boolean rightAlignMenu)
   {
      this((String)null, 
           ThemeResources.INSTANCE.menuDownArrow(), 
           (ImageResource) null,
           (ClickHandler) null);
      
      addMenuHandlers(menu, rightAlignMenu);
      
      addStyleName(styles_.toolbarButtonMenu());
      addStyleName(styles_.toolbarButtonMenuOnly());
   }
      
   public ToolbarButton(String text, 
                        ImageResource leftImage,
                        ToolbarPopupMenu menu)
   {
      this(text, leftImage, menu, false);
   }
   
   public ToolbarButton(String text,
                        ImageResourceProvider leftImage,
                        ToolbarPopupMenu menu)
   {
      this(text, leftImage, menu, false);
   }
    
   public ToolbarButton(String text, 
                        ImageResource leftImage,
                        ToolbarPopupMenu menu,
                        boolean rightAlignMenu)
   {
      this(text,
           new SimpleImageResourceProvider(leftImage),
           menu, 
           rightAlignMenu);
   }

   public ToolbarButton(String text, 
                        ImageResourceProvider leftImage,
                        ToolbarPopupMenu menu,
                        boolean rightAlignMenu)
   {
      this(text, leftImage, ThemeResources.INSTANCE.menuDownArrow(), null);

      addMenuHandlers(menu, rightAlignMenu);
      
      addStyleName(styles_.toolbarButtonMenu());
   }
   
   
   private void addMenuHandlers(final ToolbarPopupMenu popupMenu, 
                                final boolean rightAlign)
   {
      menu_ = popupMenu;
      /*
       * We want clicks on this button to toggle the visibility of the menu,
       * as well as having the menu auto-hide itself as it normally does.
       * It's necessary to manually track the visibility (menuShowing) because
       * in the case where the menu is showing, clicking on this button first
       * causes the menu to auto-hide and then our mouseDown handler is called
       * (so we can't rely on menu.isShowing(), it'll always be false by the
       * time you get into the mousedown handler).
       */

      final boolean[] menuShowing = new boolean[1];

      addMouseDownHandler(new MouseDownHandler()
      {
         public void onMouseDown(MouseDownEvent event)
         {
            event.preventDefault();
            event.stopPropagation();
            addStyleName(styles_.toolbarButtonPushed());
            // Some menus are rebuilt on every invocation. Ask the menu for 
            // the most up-to-date version before proceeding.
            popupMenu.getDynamicPopupMenu(
               new ToolbarPopupMenu.DynamicPopupMenuCallback()
            {
               @Override
               public void onPopupMenu(final ToolbarPopupMenu menu)
               {
                  if (menuShowing[0])
                  {
                     removeStyleName(styles_.toolbarButtonPushed());
                     menu.hide();
                  }
                  else
                  {
                     if (rightAlign)
                     {
                        menu.setPopupPositionAndShow(new PositionCallback() 
                        {
                           @Override
                           public void setPosition(int offsetWidth, 
                                                   int offsetHeight)
                           {
                              menu.setPopupPosition(
                                 (rightImageWidget_ != null ?
                                       rightImageWidget_.getAbsoluteLeft() :
                                       leftImageWidget_.getAbsoluteLeft())
                                 + 20 - offsetWidth, 
                                 ToolbarButton.this.getAbsoluteTop() +
                                 ToolbarButton.this.getOffsetHeight());
                           } 
                        });
                     }
                     else
                     {
                        menu.showRelativeTo(ToolbarButton.this);
                     }
                     menuShowing[0] = true;
                  }
               }
            });
         }
      });
{'fraction_non_alphanumeric': 0.07228836413865684, 'fraction_numerical': 0.001841741761494442, 'mean_word_length': 1.6575773466177242, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 30, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '979782', 'n_tokens_mistral': 3805, 'n_tokens_neox': 3659, 'n_words': 883}