# jedit_util.tcl - utility procedures for jedit, a tk-based editor
#
######################################################################
# Copyright 1995 by Jay Sekora.  This file may be freely             #
# distributed, modified or unmodified, for any purpose, provided     #
# that this copyright notice is retained verbatim in all copies and  #
# no attempt is made to obscure the authorship of this file.  If you #
# distribute any modified versions, I ask, but do not require, that  #
# you clearly mark any changes you make as such and that you provide #
# your users with instructions for getting the original sources.     #
######################################################################

######################################################################
######################################################################
### Modified version of tkMenuButtonDown from Tk4.1a1 - fixes problems
### with grabs.  This is also fixed in Tk4.0p2.
######################################################################
######################################################################

j:tk4 {
  global tk_patchLevel
  if {[info exists tk_patchLevel]} {
    if {$tk_patchLevel != "7.4p2"} {
      # Copyright (c) 1992-1994 The Regents of the University of California.
      # Copyright (c) 1994-1995 Sun Microsystems, Inc.
      # terms and disclaimer as specified in the file "license.terms"
      #   in the Tk4.1a1 distribution
      # tkMenuButtonDown --
      # Handles button presses in menus.  There are a couple of tricky things
      # here:
      # 1. Change the posted cascade entry (if any) to match the mouse position.
      # 2. If there is a posted menubutton, must grab to the menubutton;  this
      #    overrrides the implicit grab on button press, so that the menu
      #    button can track mouse motions over other menubuttons and change
      #    the posted menu.
      # 3. If there's no posted menubutton (e.g. because we're a torn-off menu
      #    or one of its descendants) must grab to the top-level menu so that
      #    we can track mouse motions across the entire menu hierarchy.
      #
      # Arguments:
      # menu -		The menu window.
      
      proc tkMenuButtonDown menu {
          global tkPriv
          $menu postcascade active
          if {$tkPriv(postedMb) != ""} {
              grab -global $tkPriv(postedMb)
          } else {
              while {[wm overrideredirect $menu]
                      && ([winfo class [winfo parent $menu]] == "Menu")
                      && [winfo ismapped [winfo parent $menu]]} {
                  set menu [winfo parent $menu]
              }
      
              # Don't update grab information if the grab window isn't changing.
              # Otherwise, we'll get an error when we unpost the menus and
              # restore the grab, since the old grab window will not be viewable
              # anymore.
      
              if {$menu != [grab current $menu]} {
                  tkSaveGrabInfo $menu
              }
      
              # Must re-grab even if the grab window hasn't changed, in order
              # to release the implicit grab from the button press.
      
              grab -global $menu
          }
      }
    }
  }
}

proc jedit:right_popup t {
  j:tk3 {return}			;# Tk3.X doesn't support tk_popup
  catch {
    destroy $t.right_popup
  }
  menu $t.right_popup -tearoff 0
  j:menu:commands $t.right_popup $t {
    jedit:cmd:indent
    jedit:cmd:unindent
    jedit:cmd:toggle_case
    jedit:cmd:fmt
    jedit:cmd:sort
    jedit:cmd:quote_email
    -
    jedit:cmd:note
    jedit:cmd:select_all
  }
  catch {
    tk_popup $t.right_popup \
      [expr [winfo pointerx $t] - 5] \
      [expr [winfo pointery $t] - 5]
  }
}

proc jedit:left_popup t {
  j:tk3 {return}			;# Tk3.X doesn't support tk_popup
  catch {
    destroy $t.left_popup
  }
  menu $t.left_popup -tearoff 0
  j:menu:commands $t.left_popup $t {
    jedit:cmd:load
    jedit:cmd:save
    jedit:cmd:saveas
    jedit:cmd:print
    jedit:cmd:insfile
    -
    jedit:cmd:undo
    jedit:cmd:redo
    jedit:cmd:save_checkpoint
    -
    jedit:cmd:new_window
    jedit:cmd:done
    jedit:cmd:close
    jedit:cmd:quit
  }
  catch {
    tk_popup $t.left_popup \
      [expr [winfo pointerx $t] - 5] \
      [expr [winfo pointery $t] - 5]
  }
}

# BIND TO <ButtonPress-N>:

proc j:tmb:start_gesture { W x y t } {
  global j_teb
  set j_teb(gesture,starttime) $t
  set j_teb(gesture,x) $x
  set j_teb(gesture,y) $y
}

# BIND TO <ButtonRelease-N>:

proc j:tmb:end_gesture { W x y t } {
  global j_teb
  
  set ydiff [expr $j_teb(gesture,y) - $y]
  set xdiff [expr $j_teb(gesture,x) - $x]
  
  set xmax [expr abs($ydiff / 2)]
  set ymax [expr abs($xdiff / 2)]
  
  ### puts stderr "y: $ydiff; x: $xdiff"
  
  if { [expr $t - $j_teb(gesture,starttime)] < 1000 } {
    if {$xdiff >= -$xmax && $xdiff <= $xmax } {
      if {$ydiff > 5} {
        ### puts stderr up
        jedit:cmd:cut $W
      }
      if {$ydiff < -5} {
        ### puts stderr down
        jedit:cmd:paste $W
      }
    } else {
      if {$ydiff >= -$ymax && $ydiff <= $ymax } {
        if {$xdiff > 5} {
          ### puts stderr left
          jedit:left_popup $W
        }
        if {$xdiff < -5} {
          ### puts stderr right
          jedit:right_popup $W
        }
      }
    }
  }
}

bind Text <ButtonPress-3> {j:tmb:start_gesture %W %x %y %t ;}
bind Text <ButtonRelease-3> {j:tmb:end_gesture %W %x %y %t ;}

j:tk4 {
  bind Text <ButtonPress-3> +break
  bind Text <ButtonRelease-3> +break
}
