Version 1 of Move any widget

Updated 2010-03-15 21:57:30 by lars_h

In my quest to develop a gui generator, I have reached a stage in which I need to provide the user the ability to explore widgets placement and do a quick and easy form layout design. Same idea as some of us are already familiar with within Visual Basic and C++. The code presented here is a simplified version in order to be able to share it with a wider tcl/tk community, from newbie to guru.

The code as presented is developed in & for (yes, the tool is creating itself) tG2 v1.06.01

Some limitations which have already been solved in tG2:

  - the titlebar height and framewidth of a toplevel is assumed fixed
  - when widgets are placed in frames, it will create another offset which needs to be taken into account, recursively...

The presented code is tested with tcl/tk v8.4.19 & WinXP OS.

# ------------------------------------------------------------------------------
bind . <Configure> {set components(geo) [split [split [wm geometry .] "x"] "+"]}

# ------------------------------------------------------------------------------
bind . <Motion> {
  if {$components(moveObject) != ""} {
    place $components(moveObject) \
      -x [expr [winfo pointerx .] - [lindex $components(geo) 1] - 3  - $objectXoff] \
      -y [expr [winfo pointery .] - [lindex $components(geo) 2] - 29 - $objectYoff]
  }
}

# ------------------------------------------------------------------------------
proc makeMovableObject {w} {
  set cmd "bind $w  <Motion>    \{$w config -cursor crosshair\}"; eval $cmd
  set cmd "bind $w  <Leave>     \{$w config -cursor \"\"\}"; eval $cmd
  set cmd "bind $w  <ButtonPress-1>   \{+; 
    set objectXoff \[expr %x]
    set objectYoff \[expr %y]
    set components(moveObject) $w
    eval \[bind . <Motion>\]
  \}"
  eval $cmd
  
  bind $w <ButtonRelease-1> {+; 
    set components(moveObject) ""
  }
}

set components(moveObject) ""
eval [bind . <Configure>]

# ---------------------------------- TEST CODE ---------------------------------
button .button1 -text "hello world"
place .button1 -x 50 -y 50
makeMovableObject .button1

label .label1 -text "hello again"
place .label1 -x 50 -y 80
makeMovableObject .label1