# <20210821.1525.08>
# This is an implementation of the size grip widget using
# simple buttons and bitmaps.
#
# This code sets up the  button and the bindings. We size it
# to 10x10, with a border of 1 but feel free to do what ever
# you want after the fact.

proc segrip {w args} {
  # se (south east size grip) for window with toplevel "w"
  if {$args == {}} {
    set args  [list -data "
 	 #define gripse_width 12
 	  #define gripse_height 12
  	  static char gripse_bits = {
   	   0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x80, 0x01,
    	   0xc0, 0x02, 0x60, 0x03, 0xb0, 0x01, 0xd8, 0x02,
    	   0x6c, 0x03, 0xb6, 0x01, 0x00, 0x00, 0x00, 0x00}"] 
  }
  buildGripButton $w se [getImage bitmap seGrip {*}$args]
}

proc swgrip {w args} {
  # sw (south west size grip) for window with toplevel "w"
  if {$args == {}} {
    set args [list -data "
 	#define gripsw_width 16
        #define gripsw_height 16
        static char gripsw_bits = {
        0x00, 0x00, 0x08, 0x00, 0x18, 0x00, 0x30, 0x00, 
        0x60, 0x00, 0xd8, 0x00, 0xb0, 0x01, 0x68, 0x03, 
        0xd8, 0x06, 0xb0, 0x0d, 0x68, 0x1b, 0xd8, 0x36,
        0xb0, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}"]
  }
  buildGripButton $w sw [getImage bitmap swGrip {*}$args]
} 

proc buildGripButton {w se bm} {
  set cursor [expr {$se == "se" ? "bottom_right_corner" : \
			"bottom_left_corner"}]
  button $w.${se}grip -width 10 -height 10 -cursor $cursor {*}$bm
  # use the ttk widget code for south east and Release
  # the ttk folks did not do a south west and their Press depends on the
  # ttk-widget instate command which is not available in button
  # and define a mod for south west
  bind $w.${se}grip <1>               {ttk::sizegrip::PressX  %W %X %Y} 
  bind $w.${se}grip <ButtonRelease-1> {ttk::sizegrip::Release %W %X %Y}
  if {$se == "se"} {
    bind $w.${se}grip <B1-Motion>     {ttk::sizegrip::Drag    %W %X %Y}
  } else {	     
    bind $w.${se}grip <B1-Motion>     {ttk::sizegrip::Dragsw  %W %X %Y}
  }
  bind $w.${se}grip <Enter>           [list $w.${se}grip config -cursor $cursor]
  return $w.${se}grip
}

proc ttk::sizegrip::PressX {W X Y} {

  variable State

  if {[$W cget -state] ==  "disabled"} { return }

  set top [winfo toplevel $W]

  # If the toplevel is not resizable then bail
  foreach {State(resizeX) State(resizeY)} [wm resizable $top] break
  if {!$State(resizeX) && !$State(resizeY)} {
    return
  }

  # Sanity-checks:
  #	If a negative X or Y position was specified for [wm geometry],
  #   just bail out -- there's no way to handle this cleanly.
  #
  if {[scan [wm geometry $top] "%dx%d+%d+%d" width height x y] != 4} {
    return;
  }

  # Account for gridded geometry:
  #
  set grid [wm grid $top]
  if {[llength $grid]} {
    set State(widthInc) [lindex $grid 2]
    set State(heightInc) [lindex $grid 3]
  } else {
    set State(widthInc) [set State(heightInc) 1]
  }

  set State(toplevel) $top
  set State(pressX) $X
  set State(pressY) $Y
  set State(width)  $width
  set State(height) $height
  set State(x)      $x
  set State(y)      $y
  set State(pressed) 1
}

proc ttk::sizegrip::Dragsw {W X Y} {
  variable State
  if {!$State(pressed)} { return }
  set w $State(width)
  set h $State(height)
  if {$State(resizeX)} {
    set w [expr {$w - ($X - $State(pressX))/$State(widthInc)}]
  }
  if {$State(resizeY)} {
    set h [expr {$h + ($Y - $State(pressY))/$State(heightInc)}]
  }
  if {$w <= 0} { set w 1 }
  if {$h <= 0} { set h 1 }
  set x [expr {$State(x) + $State(width) - $w}]
  set y $State(y)
  wm geometry $State(toplevel) ${w}x${h}+${x}+${y}
}

# proc sizeGripRelease {W X Y} {
#   variable State
#   set State(pressed) 0
# }
