[Gambas-user] Menu events in 1.9.34 (attachment)

Allen Murphy msumurph at ...626...
Tue Jul 25 02:33:45 CEST 2006


Sorry, forgot to attach the patch.


On Mon, 2006-07-24 at 20:29 -0400, Allen Murphy wrote:
> I did some snooping around and found the offending commented code.
> 
> In file FForm.class located in ../gambas2-1.9.34/app/src/gambas2, I
> un-commented lines 1464 to 1468:
> 
> PUBLIC SUB Menu_Click()
>  
>   Control_DblClick
> 
> END
> 
> This seems to have fixed the problem.  I have attached the patched file.
> Benoit can verify if I found the right section of problem code.
> 
> Take care,
> Allen
> 
> On Tue, 2006-07-25 at 01:27 +0200, Benoit Minisini wrote:
> > On Tuesday 25 July 2006 01:06, Allen Murphy wrote:
> > > Greetings!
> > >
> > > I have noticed that in the Gambas2 1.9.34 Form Designer, when I click a
> > > menu item I have created, I am not sent to the Code Editor as in Gambas
> > > 1.0.17.
> > >
> > > For example, if I have a menu named mnuFile with a child item named
> > > itmQuit, I am not sent to the event handler "PUBLIC SUB itmQuit_Click()"
> > > when I click on that item.
> > >
> > > Is this by design, or am I missing something?
> > >
> > > Thanks,
> > > Allen
> > >
> > 
> > No, this is a bug. Some line of code I commented and forgot to uncomment.
> > 
> 
> 
> -------------------------------------------------------------------------
> Take Surveys. Earn Cash. Influence the Future of IT
> Join SourceForge.net's Techsay panel and you'll get the chance to share your
> opinions on IT & business topics through brief surveys -- and earn cash
> http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
> _______________________________________________
> Gambas-user mailing list
> Gambas-user at lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/gambas-user
-------------- next part --------------
' Gambas class file

PUBLIC Name AS String
PUBLIC Path AS String
PUBLIC Master AS CControl
PUBLIC Selection AS NEW Collection
PUBLIC Control AS Collection
PUBLIC Menus AS NEW Object[]

PUBLIC Container AS Container

PRIVATE $bDoNotModify AS Boolean
PRIVATE $bModify AS Boolean
PRIVATE $bSelChange AS Boolean
PRIVATE $bReadOnly AS Boolean
PRIVATE $bActivate AS Boolean

PRIVATE $sType AS String

' Gestion de la souris

PRIVATE $iMode AS Integer

PRIVATE CONST MODE_NOTHING AS Integer = 0
PRIVATE CONST MODE_CREATE AS Integer = 1
PRIVATE CONST MODE_MOVE AS Integer = 2
PRIVATE CONST MODE_SELECT AS Integer = 3

PRIVATE $sTool AS String
PRIVATE $hCurrent AS CControl
PRIVATE $X AS Integer
PRIVATE $Y AS Integer
PRIVATE $MX AS Integer
PRIVATE $MY AS Integer
PRIVATE $W AS Integer
PRIVATE $H AS Integer
PRIVATE $bMove AS Boolean

PRIVATE $XS AS Integer
PRIVATE $YS AS Integer
PRIVATE $WS AS Integer
PRIVATE $HS AS Integer

PRIVATE CONST MIN_WIDTH AS Integer = 4
PRIVATE CONST MIN_HEIGHT AS Integer = 4

' Gestion de la sauvegarde

PRIVATE $sSave AS String
PRIVATE $iSaveX AS Integer
PRIVATE $iSaveY AS Integer
'PRIVATE $iIndent AS INTEGER
PRIVATE $iSaveLevel AS Integer
PRIVATE $bSelectNew AS Boolean
PRIVATE $bDoNotArrange AS Boolean


PRIVATE CONST FORM_CLIPBOARD_FORMAT AS String = "text/x-gambas-form"

'PRIVATE CONST FORM_NAME AS String = "$"

PUBLIC SUB _new(sPath AS String)

  DIM sData AS String

  btnCloseWindow.Design = TRUE
  btnMaxWindow.Design = TRUE

  Path = sPath
  Name = File.BaseName(sPath)
  Control = NEW Collection(gb.Text)
  Container = panBorder

  'mnuSave.Enabled = NOT Project.ReadOnly
  SetReadOnly

  '$sType = "Form"

  sData = File.Load(sPath)

  IF UCase(Left$(sData, Len(Project.FORM_MAGIC))) <> UCase(Project.FORM_MAGIC) THEN
    Message.Warning(("Bad form file"))
    RETURN
  ENDIF

  'ME.Font.Size = 10

  $bDoNotModify = TRUE

  sData = Mid$(sData, Len(Project.FORM_MAGIC) + 1)
  FromString(sData)

  UpdateSnap

  DrawTitle

  RefreshMenu
  
  $bDoNotModify = FALSE

END

PUBLIC SUB UpdateSnap()
  
  DIM hPict AS Picture
  DIM hCtrl AS CControl = Control[Name]

  IF Project.ShowGrid THEN

    hPict = NEW Picture(Project.Snap, Project.Snap)
    hPict.Fill(hCtrl.Control.Background)
    Draw.Begin(hPict)
    Draw.Invert = TRUE
    Draw.ForeColor = Color.White
    Draw.Point(0, 0)
    Draw.End
    hCtrl.Control.Picture = hPict
    
  ELSE
  
    hCtrl.Control.Picture = NULL
    
  ENDIF
  
END



PRIVATE FUNCTION UnquoteString(sVal AS String) AS String
  
  'sVal = Mid$(sVal, 2, Len(sVal) - 2)
  sVal = Replace(sVal, "\\n", gb.NewLine)
  sVal = Replace(sVal, "\\" & Chr$(34), Chr$(34))
  sVal = Replace(sVal, "\\\\", "\\")
  RETURN sVal
  
END



PRIVATE SUB FromString(sData AS String, OPTIONAL hParent AS CControl)

  DIM hCtrl AS Object
  'DIM hParent AS OBJECT

  DIM sName AS String
  DIM sClass AS String
  DIM iPos AS Integer
  DIM sLine AS String
  DIM hData AS CControl

  DIM sProperty AS String
  DIM sValue AS String
  DIM vValue AS Variant
  DIM aVal AS String[]
  DIM iInd AS Integer

  DIM iLevel AS Integer
  DIM bFirst AS Boolean
  DIM sEventName AS String

  DIM cCoord AS String[]

  hCtrl = hParent
  bFirst = TRUE

  WHILE sData

    iPos = InStr(sData, gb.newLine)
    IF iPos = 0 THEN
      sLine = Trim(sData)
      sData = ""
    ELSE
      sLine = Trim(Left$(sData, iPos - 1))
      sData = Mid$(sData, iPos + 1)
    ENDIF

    'PRINT "> "; sLine

    IF Len(sLine) = 0 THEN CONTINUE
    IF Left$(sLine, 1) = "#" THEN sLine = Mid$(sLine, 2)

    IF Left$(sLine, 1) = "{" THEN

      sLine = Trim(Mid$(sLine, 2))
      iPos = InStr(sLine, " ")
      sName = Left$(sLine, iPos - 1)
      sClass = Trim(Mid$(sLine, iPos + 1))
      iPos = InStr(sClass, " ")
      IF iPos THEN
        sEventName = Trim(Mid$(sClass, iPos + 1))
        sClass = Trim(Left$(sClass, iPos - 1))
      ELSE
        sEventName = ""
      ENDIF

      IF Left$(sClass) = "#" THEN sClass = Mid$(sClass, 2)

      IF IsNull(hCtrl) THEN sName = Name

      IF sClass = "Image" THEN
        PRINT "Image -> PictureBox"
        sClass = "PictureBox"
      ENDIF

      hCtrl = CreateControl(sClass, hCtrl, sName)

      IF sEventName THEN hCtrl.SetProperty(CPropertyInfo.EVENT_NAME, sEventName)

      INC iLevel

    ELSE IF Left$(sLine, 1) = "}" THEN

      'IF hCtrl = hParent THEN RETURN
      DEC iLevel

      IF iLevel = 0 THEN
        IF $bSelectNew THEN
          hCtrl.Select(ME, bFirst)
          bFirst = FALSE
        ENDIF
      ENDIF

      hCtrl = hCtrl.Parent

    ELSE

      iPos = InStr(sLine, "=")

      IF iPos THEN

        sProperty = Trim(Left$(sLine, iPos - 1))
        sValue = Trim(Mid$(sLine, iPos + 1))

        vValue = Val(sValue)
        IF IsNull(vValue) THEN

          IF Left$(sValue, 2) = "(" & Chr$(34) THEN
            sValue = Mid$(sValue, 2, -1)
          ENDIF

          IF Left$(sValue, 1) = Chr$(34) THEN
            vValue = UnquoteString(Mid$(sValue, 2, -1))
          ELSE IF Left$(sValue) = "[" THEN
            aVal = Split(Mid$(sValue, 2, -1), ", ", Chr$(34), TRUE)
            FOR iInd = 0 TO aVal.Max
              aVal[iInd] = UnquoteString(aVal[iInd])
            NEXT
            vValue = aVal '.Join("\n")
          ELSE IF Left$(sValue, 5) = "Font[" THEN
            vValue = Mid$(sValue, 7, -2)
          ELSE IF Left$(sValue, 8) = "Picture[" THEN
            vValue = Mid$(sValue, 10, -2)
            'PRINT File.Dir(Project.Path) &/ Mid$(sValue, 9, -1)
            'vValue = Picture[File.Dir(Project.Path) &/ Mid$(sValue, 9, -1)]
          ELSE IF UCase(sValue) = "TRUE" THEN
            vValue = TRUE
          ELSE IF UCase(sValue) = "FALSE" THEN
            vValue = FALSE
          ELSE IF Left$(sValue, 6) = "CDate(" THEN
            vValue = CDate(Mid$(sValue, 8, -2))
          ELSE

            iPos = InStr(sValue, ".")
            IF iPos THEN
              vValue = Mid$(sValue, iPos + 1)
            ELSE
              PRINT "Bad property value "; sValue
              ' This is an object !
            ENDIF

          ENDIF

        ENDIF

        IF hCtrl.SetProperty(sProperty, vValue) THEN
          PRINT "Error: "; hCtrl.Kind; "."; sProperty; " = "; sValue
        ENDIF

      ELSE IF Left$(sLine, 5) = "Move(" THEN

        cCoord = Split(Mid$(sLine, 6, -1))
        'TRY PRINT cCoord[0]; ","; cCoord[1]; ","; cCoord[2]; ","; cCoord[3]
        TRY hCtrl.Move(CInt(cCoord[0]) / Project.Snap * Desktop.Scale, CInt(cCoord[1]) / Project.Snap * Desktop.Scale, TRUE)
        'TRY hCtrl.SetProperty("X", Val(cCoord[0]))
        'TRY hCtrl.SetProperty("Y", Val(cCoord[1]))
        IF cCoord.Count >= 2 THEN
          TRY hCtrl.Resize(CInt(cCoord[2]) / Project.Snap * Desktop.Scale, CInt(cCoord[3]) / Project.Snap * Desktop.Scale, TRUE)
        ENDIF

        IF ERROR THEN PRINT "Error: Syntax error: "; sLine

      ELSE IF Left$(sLine, 11) = "MoveScaled(" THEN

        cCoord = Split(Mid$(sLine, 12, -1))
        'TRY PRINT cCoord[0]; ","; cCoord[1]; ","; cCoord[2]; ","; cCoord[3]
        TRY hCtrl.Move(CFloat(cCoord[0]) * Desktop.Scale, CFloat(cCoord[1]) * Desktop.Scale, TRUE)
        'TRY hCtrl.SetProperty("X", Val(cCoord[0]))
        'TRY hCtrl.SetProperty("Y", Val(cCoord[1]))
        IF cCoord.Count >= 2 THEN
          TRY hCtrl.Resize(CFloat(cCoord[2]) * Desktop.Scale, CFloat(cCoord[3]) * Desktop.Scale, TRUE)
        ENDIF

        IF ERROR THEN PRINT "Error: Syntax error: "; sLine

      ELSE IF Left$(sLine) <> "'" THEN

        PRINT "Error: Syntax error: "; sLine

      ENDIF

    ENDIF

  WEND

END


PUBLIC FUNCTION Save() AS Boolean

  DIM hFic AS File

  IF Project.ReadOnly THEN RETURN
  IF NOT $bModify THEN RETURN

  UnselectAll

  Save.Begin(Path)

  ResetSave

  AddLine(Project.FORM_MAGIC)
  AddLine()

  SaveOne(Control[Name])

  File.Save(Path, $sSave)

  Project.SetFormIcon(ME)

  'OPEN Path & ".test" FOR CREATE AS #hFic ' y a un truc bizarre avec CREATE !
  'PRINT #hFic, $sSave
  'CLOSE #hFic

  $sSave = ""
  $bModify = FALSE
  DrawTitle

  Save.End()

CATCH

  RETURN Save.Error()

END


PUBLIC SUB AddLine(OPTIONAL sLig AS String)

  DIM sAdd AS String

  'IF Left$(sLig, 1) = "}" THEN $iIndent = $iIndent - 1

  sAdd = Space$($iSaveLevel * 2) & sLig
  'PRINT sAdd
  $sSave = $sSave & sAdd & gb.NewLine

  'IF Left$(sLig, 1) = "{" THEN $iIndent = $iIndent + 1

END


PUBLIC FUNCTION GetChildren(sName AS String) AS Object[]

  DIM cList AS NEW Object[]
  DIM hCtrl AS CControl
  DIM hChild AS Control
  DIM iTab AS Integer
  DIM hMenu AS Menu
  DIM hTab AS Object 'TabStrip

  hCtrl = Control[sName]
  IF IsNull(hCtrl) THEN RETURN
  IF NOT hCtrl.IsContainer() THEN RETURN

  IF hCtrl.Kind = "Form" THEN

    FOR EACH hMenu IN ME.Menus
      cList.Add(Control[hMenu.Tag])
    NEXT

    FOR EACH hChild IN hCtrl.Control.Children
      cList.Add(Control[hChild.Tag])
    NEXT

  'ELSE IF hCtrl.Kind = "TabStrip" THEN
  ELSE IF hCtrl.IsMultiContainer() THEN

    hTab = hCtrl.Control

    FOR iTab = 0 TO hTab.Count - 1

      FOR EACH hChild IN hTab[iTab].Children
        cList.Add(Control[hChild.Tag])
      NEXT

    NEXT

  ELSE IF hCtrl.Kind = "Menu" THEN

    FOR EACH hMenu IN hCtrl.Control.Children
      cList.Add(Control[hMenu.Tag])
    NEXT

  ELSE

    FOR EACH hChild IN hCtrl.Control.Children
      cList.Add(Control[hChild.Tag])
    NEXT

  ENDIF

  RETURN cList

END



PRIVATE SUB SaveOne(hCtrl AS CControl)

  DIM hChild AS Control
  DIM sLine AS String
  DIM hMenu AS Menu
  DIM hMenuCtrl AS CControl
  DIM cProp AS String[]

  DIM hTab AS Object
  DIM hSubTab AS Object
  DIM iTab AS Integer
  DIM sVal AS String
  DIM vVal AS Variant
  DIM iArr AS Integer
  DIM sText AS String

  'hCtrl = Control[sName]
  'PRINT "SaveOne: hCtrl = "; hCtrl
  IF IsNull(hCtrl) THEN RETURN

  IF hCtrl.Virtual THEN
    AddLine(Trim("{ " & hCtrl.Name & " #" & hCtrl.Kind & " " & hCtrl.GetProperty(CPropertyInfo.EVENT_NAME)))
  ELSE
    AddLine(Trim("{ " & hCtrl.Name & " " & hCtrl.Kind & " " & hCtrl.GetProperty(CPropertyInfo.EVENT_NAME)))
  ENDIF

  IF $iSaveLevel = 0 THEN
    cProp = hCtrl.GetEachProperty($iSaveX, $iSaveY)
  ELSE
    cProp = hCtrl.GetEachProperty(0, 0)
  ENDIF

  $iSaveLevel = $iSaveLevel + 1

  FOR EACH sLine IN cProp
    AddLine(sLine)
  NEXT

  IF hCtrl.IsContainer() THEN

    IF NOT $bDoNotArrange THEN
    
      TRY iArr = CComponent.Classes[$sType &/ hCtrl.Kind].Symbols["_Arrangement"].Value
  
      IF NOT ERROR THEN
  
        IF iArr = Arrange.Fill THEN
          iArr = 0
          TRY iArr = CComponent.Classes[$sType &/ "Arrange"].Symbols[hCtrl.GetProperty("Arrangement")].Value
        ENDIF
  
        IF iArr THEN
  
          'IF hCtrl.Kind = "TabStrip" THEN
          IF hCtrl.IsMultiContainer() THEN
  
          ELSE
  
            ArrangeContainer(hCtrl.Control, iArr, FALSE)
  
          ENDIF
  
        ENDIF
  
      ENDIF
      
    ENDIF

    IF hCtrl.Kind = "Form" THEN

      FOR EACH hMenuCtrl IN ME.Menus
        SaveOne(hMenuCtrl)
      NEXT

      FOR EACH hChild IN hCtrl.Control.Children
        'PRINT "SaveOne? "; Object.Type(hChild);; hChild.Tag; " "; Control[hChild.Tag]
        SaveOne(Control[hChild.Tag])
      NEXT

    'ELSE IF hCtrl.Kind = "TabStrip" THEN
    ELSE IF hCtrl.IsMultiContainer() THEN

      hTab = hCtrl.Control

      FOR iTab = 0 TO hTab.Count - 1

        AddLine("Index = " & CStr(iTab))
        sVal = Replace(hTab[iTab].Text, "\\", "\\\\")
        sVal = Replace(sVal, Chr$(34), "\\" & Chr$(34))
        sVal = Replace(sVal, gb.NewLine, "\\n")
        AddLine("Text = (" & Chr$(34) & sVal & Chr$(34) & ")")

        IF hCtrl.Tag THEN
          sVal = hCtrl.Tag[iTab]
          IF sVal THEN
            AddLine("Picture = Picture[" & Chr$(34) & sVal & Chr$(34) & "]")
          ENDIF
        ENDIF

        FOR EACH hChild IN hTab[iTab].Children
          SaveOne(Control[hChild.Tag])
        NEXT

      NEXT

      'AddLine("Index = " & CStr(hTab.Index))
      AddLine("Index = 0")

    ELSE IF hCtrl.Kind = "Menu" THEN

      FOR EACH hMenu IN hCtrl.Control.Children
        SaveOne(Control[hMenu.Tag])
      NEXT

    ELSE

      FOR EACH hChild IN hCtrl.Control.Children
        SaveOne(Control[hChild.Tag])
      NEXT

    ENDIF

  ENDIF

  $iSaveLevel = $iSaveLevel - 1

  AddLine("}")

END



PUBLIC SUB Control_Resize()

  DIM hCtrl AS Control = LAST

  WITH Control[Name]
    IF hCtrl <> .Control THEN RETURN
    IF hCtrl.Width <> .GetProperty("Width") THEN .SetProperty("Width", hCtrl.Width)
    IF hCtrl.Height <> .GetProperty("Height") THEN .SetProperty("Height", hCtrl.Height)
  END WITH

END


'PUBLIC SUB Form_KeyPress(Ascii AS String, Code AS Integer, State AS Integer)
'
'  Project.Shortcut(Code, Ascii, State)
'
'END


PRIVATE $bInFormMove AS Boolean

' PUBLIC SUB Form_Move()
' 
'   DIM X, Y AS Integer
' 
'   IF NOT LAST.Visible THEN RETURN
'   IF $bInFormMove THEN RETURN
' 
'   $bInFormMove = TRUE
' 
'   'DEBUG ME.Name;; ME.X;; ME.Y
' 
'   WITH Control[Name]
' 
'     X = .GetProperty("X") 
'     Y = .GetProperty("Y") 
'     
'     'DEBUG X;; Y;; "->";; ME.X;; ME.Y;; X <> ME.X;; Y <> ME.Y
'     
'     IF X <> ME.X THEN .SetProperty("X", ME.X, TRUE)
'     IF Y <> ME.Y THEN .SetProperty("Y", ME.Y, TRUE)
' 
'   END WITH
' 
'   $bInFormMove = FALSE
' 
' END


PUBLIC SUB Control_MouseDown()

  'PRINT "> Control_MouseDown"

  DIM X AS Integer
  DIM Y AS Integer

  ME.SetFocus

  X = Mouse.X
  Y = Mouse.Y

  $hCurrent = Control[LAST.Tag]
  $sTool = FToolBox.GetTool()

  $X = LAST.X
  $Y = LAST.Y
  $MX = LAST.ScreenX + X
  $MY = LAST.ScreenY + Y

  'IF $hCurrent.Kind = "GridView" THEN
  '  PRINT "MouseDown: $X ="; $X; " $Y ="; $Y; " $MX ="; $MX; " $MY ="; $MY
  '  PRINT "X ="; X; " Y ="; Y
  'ENDIF

  IF $sTool = "" THEN

    IF Mouse.Control OR $hCurrent.Name = Name THEN

      $XS = X
      $YS = Y

      $iMode = MODE_SELECT

      $W = 0
      $H = 0

      GOTO FIN

    ELSE

      IF Master <> $hCurrent THEN

        IF NOT $hCurrent.Selected THEN
          UnSelectAll
        ENDIF

        SelectCurrent(TRUE)

      ENDIF

      IF $bReadOnly THEN RETURN

      $iMode = MODE_MOVE

    ENDIF

  ELSE

    IF $bReadOnly THEN RETURN

    IF NOT $hCurrent.IsContainer() THEN
      X = X + $hCurrent.Control.X + $hCurrent.Control.Parent.ClientX
      Y = Y + $hCurrent.Control.Y + $hCurrent.Control.Parent.ClientY
      $hCurrent = $hCurrent.Parent
      IF $hCurrent.Kind = "ScrollView" THEN
        X = X - $hCurrent.Control.ScrollX
        Y = Y - $hCurrent.Control.ScrollY
      ENDIF
    ENDIF

    $iMode = MODE_CREATE

    $X = X
    $Y = Y

    '$hCurrent = CreateControl(, $sTool, $hCurrent)
  ENDIF

  RefreshProperty

FIN:
  'PRINT "< Control_MouseDown"

END

PUBLIC SUB Control_MouseMove()

  DIM X AS Integer
  DIM Y AS Integer
  DIM iDepX AS Integer
  DIM iDepY AS Integer
  DIM hCtrl AS CControl
  DIM W AS Integer
  DIM H AS Integer
  DIM bMoveX AS Boolean
  DIM bMoveY AS Boolean
  DIM hParent AS CControl

  IF NOT Mouse.Left THEN RETURN

  'PRINT "Control_MouseMove  Mode ="; $iMode

  IF Mouse.Shift THEN CControl.SetGrid(FALSE)

  X = Mouse.X
  Y = Mouse.Y

  IF $iMode = MODE_CREATE THEN

    IF LAST.Mouse <> Mouse.Cross THEN

      LAST.Mouse = Mouse.Cross

      hParent = $hCurrent
      $hCurrent = CreateControl($sTool, hParent)
      FFormStack.RefreshAll

      $X = $X - hParent.Control.ClientX
      $Y = $Y - hParent.Control.ClientY

      IF hParent.Kind = "ScrollView" THEN
        $X = $X + hParent.Control.ScrollX
        $Y = $Y + hParent.Control.ScrollY
      ENDIF

      $hCurrent.Move($X, $Y)
      $hCurrent.Resize(MIN_WIDTH, MIN_HEIGHT)
      $hCurrent.Control.Mouse = Mouse.Cross

    ENDIF

    W = Mouse.ScreenX - $MX
    IF (W < 0) THEN
      W = Abs(W)
      X = $X - W
      bMoveX = TRUE
    ELSE
      X = $X
    ENDIF

    H = Mouse.ScreenY - $MY
    IF (H < 0) THEN
      H = Abs(H)
      Y = $Y - H
      bMoveY = TRUE
    ELSE
      Y = $Y
    ENDIF

    IF bMoveX OR bMoveY THEN
      $hCurrent.Move(X, Y)
      IF bMoveX THEN W = W + X - $hCurrent.Control.X
      IF bMoveY THEN H = H + Y - $hCurrent.Control.Y
    ENDIF

    $hCurrent.Resize(Max(MIN_WIDTH, W), Max(MIN_HEIGHT, H))

  ELSE IF $iMode = MODE_MOVE THEN

    IF LAST = $hCurrent.Control THEN

      LAST.Mouse = Mouse.SizeAll

      WITH $hCurrent

        iDepX = Master.Control.X
        iDepY = Master.Control.Y

        Master.Move($X + Mouse.ScreenX - $MX, $Y + Mouse.ScreenY - $MY)

        iDepX = Master.Control.X - iDepX
        iDepY = Master.Control.Y - iDepY

        IF iDepX <> 0 OR iDepY <> 0 THEN
          FOR EACH hCtrl IN Selection
            IF hCtrl <> Master THEN
              hCtrl.Move(hCtrl.Control.X + iDepX, hCtrl.Control.Y + iDepY, TRUE)
            ENDIF
          NEXT
        ENDIF

      END WITH

    ENDIF

  ELSE IF $iMode = MODE_SELECT THEN

    DrawRectSelect(Mouse.ScreenX - $MX, Mouse.ScreenY - $MY)

  ENDIF

  CControl.SetGrid(TRUE)

END


PUBLIC SUB Control_MouseUp()

  DIM hCont AS Container
  DIM hCtrl AS CControl

  'PRINT "Control_MouseUp  Mode ="; $iMode

  IF $iMode = MODE_CREATE THEN

    'LAST.Mouse = Mouse.Arrow

    UnSelectAll

    IF LAST.Mouse = Mouse.Cross THEN
      $hCurrent.Control.Mouse = Mouse.Arrow
      SelectCurrent(TRUE)
    ENDIF

    FToolBox.SetTool()

  ELSE IF $iMode = MODE_SELECT THEN

    $WS = $W
    $HS = $H

    DrawRectSelect(0, 0)

    IF Abs($WS) > 1 AND Abs($HS) > 1 THEN

      IF NOT $hCurrent.IsContainer() THEN
        $XS = $XS + $hCurrent.Control.X
        $YS = $YS + $hCurrent.Control.Y
        $hCurrent = $hCurrent.Parent
      ENDIF

      IF Selection.Count THEN
        IF Master.Parent <> $hCurrent THEN
          UnselectAll
        ELSE IF (Mouse.Control) = 0 THEN
          UnselectAll
        ENDIF
      ENDIF

      SelectIn($hCurrent, $XS, $YS, $WS, $HS)

    ELSE

      IF $hCurrent.Name = Name THEN

        UnselectAll

      ELSE IF $hCurrent.Selected THEN

        IF Master <> $hCurrent OR Selection.Count = 1 THEN
          UnselectCurrent
        ENDIF

      ELSE

        IF Master = NULL THEN
          SelectCurrent(TRUE)
        ELSE IF $hCurrent.Parent = Master.Parent THEN
          SelectCurrent
        ELSE
          UnSelectAll
          SelectCurrent(TRUE)
        ENDIF

      ENDIF

    ENDIF

  ENDIF

  LAST.Mouse = Mouse.Arrow
  $hCurrent = NULL
  $iMode = MODE_NOTHING

  RefreshProperty

END


PUBLIC SUB Control_Menu()

  CreateMenu
  mnuForm.Popup

END


' TabStrip

PUBLIC SUB Control_Click()

  'IF Object.Type(LAST) = "TabStrip" THEN
  IF CComponent.Classes[Object.Type(LAST)].MultiContainer THEN
    WITH Control[LAST.Tag]
      $bDoNotModify = TRUE
      .SetProperty("Picture", .Tag[LAST.Index])
      .SetProperty("Text", LAST.Text)
      $bDoNotModify = FALSE
    END WITH
  ENDIF

END

PUBLIC SUB Control_KeyPress()
  
  Form_KeyPress
  
END



PUBLIC FUNCTION CreateControl(sClass AS String, hParent AS CControl, OPTIONAL sName AS String) AS CControl

  DIM hCtrl AS CControl

  IF Len(sName) = 0 THEN sName = GetName(sClass)
  IF Control.Exist(sName) THEN sName = GetName(sClass)

  ' If the component is not loaded, then return null
  IF NOT CComponent.Classes.Exist($sType &/ sClass) THEN
    Error.Raise("Component missing")
  ENDIF

  hCtrl = NEW CControl(sName, sClass, hParent, ME)

  Control[sName] = hCtrl

  IF sClass = "Menu" THEN
    IF hParent.Name = Name THEN
      Menus.Add(hCtrl)
    ENDIF
  ENDIF

  ResetClassScan

  RETURN hCtrl

  'PRINT "< CreateControl "; sName

END

PRIVATE SUB ResetClassScan()

  TRY Project.Files[File.Dir(Path) &/ Name & ".class"].Scan = NULL

END



PUBLIC SUB AddControl(sClass AS String)

  DIM hParent AS CControl

  IF Master THEN
    IF Master.IsContainer() THEN
      hParent = Master
    ELSE
      hParent = Master.Parent
    ENDIF
  ELSE
    hParent = Control[Name]
  ENDIF

  hParent = CreateControl(sClass, hParent)
  'hParent.Resize(MIN_WIDTH, MIN_HEIGHT)
  hParent.Resize(64, 32)

END



PRIVATE SUB RemoveControl(sName AS String)

  'PRINT "> RemoveControl "; sName; " "; Control[sName]
  Control[sName].Control.Delete
  Control.Remove(sName)
  Modify
  'PRINT "< RemoveControl "; sName; " "; Control[sName]

END


PRIVATE FUNCTION GetName(sClass AS String) AS String

  DIM iNum AS Integer
  DIM sName AS String
  DIM hCtrl AS CControl

  DO

    iNum = iNum + 1
    sName = sClass & Trim(CStr(iNum))

    IF NOT Control.Exist(sName) THEN EXIT

  LOOP

  RETURN sName

END


PUBLIC PROCEDURE UnSelectAll()

  DIM hCtrl AS CControl

  FOR EACH hCtrl IN Selection
    hCtrl.UnSelect(ME, TRUE)
  NEXT

  Selection.Clear
  Master = NULL
  SelectionChange

  'RefreshProperty

END


PRIVATE PROCEDURE SelectCurrent(OPTIONAL bMaster AS Boolean)

  $hCurrent.Select(ME, bMaster)
  SelectionChange

END


PRIVATE SUB UnSelectCurrent()

  $hCurrent.UnSelect(ME)
  SelectionChange
  'RefreshProperty

END


PRIVATE SUB SelectIn(hParent AS CControl, X AS Integer, Y AS Integer, W AS Integer, H AS Integer)

  DIM hChild AS Control
  DIM hCtrl AS CControl
  DIM bFirst AS Boolean

  IF W < 0 THEN
    X = X + W
    W = - W
  ENDIF

  IF H < 0 THEN
    Y = Y + H
    H = - H
  ENDIF

  'PRINT hParent.Name; X; Y; W; H

  IF W < 2 OR H < 2 THEN RETURN

  X = X - hParent.Control.ClientX
  Y = Y - hParent.Control.ClientY

  IF hParent.Kind = "ScrollView" THEN

    X = X + hParent.Control.ScrollX
    Y = Y + hParent.Control.ScrollY

  ENDIF

  bFirst = TRUE

  FOR EACH hChild IN hParent.Control.Children

    hCtrl = Control[hChild.Tag]

    IF IsNull(hCtrl) THEN CONTINUE 'panel

    IF hChild.X >= (X + W) THEN CONTINUE
    IF hChild.Y >= (Y + H) THEN CONTINUE
    IF (hChild.X + hChild.W) < X THEN CONTINUE
    IF (hChild.Y + hChild.H) < Y THEN CONTINUE

    hCtrl.Select(ME, bFirst)
    $bSelChange = TRUE
    bFirst = FALSE

  NEXT

  IF $bSelChange THEN
    SelectionChange
  ENDIF

END


PRIVATE SUB DrawRectSelect(W AS Integer, H AS Integer)

  DIM X AS Integer
  DIM Y AS Integer

  IF W = $W AND H = $H THEN RETURN

  Draw.Begin(ME)
  Draw.Invert = TRUE
  Draw.ForeColor = Color.White
  Draw.LineWidth = 1
  Draw.LineStyle = LINE.Dash

  X = $MX - ME.ScreenX
  Y = $MY - ME.ScreenY

  IF $W <> 0 AND $H <> 0 THEN Draw.Rect(X, Y, $W, $H)
  IF W <> 0 AND H <> 0 THEN Draw.Rect(X, Y, W, H)

  Draw.End

  $W = W
  $H = H

END


PUBLIC SUB DeleteSelection()

  DIM hCtrl AS CControl
  DIM cCopy AS NEW Object[]
  DIM hParent AS CControl

  IF Selection.Count THEN

    hParent = Master.Parent

    FOR EACH hCtrl IN Selection
      cCopy.Add(hCtrl)
    NEXT

    UnSelectAll

    FOR EACH hCtrl IN cCopy
      hCtrl.Delete
    NEXT

    Modify

    hParent.Select(ME, TRUE)

    ResetClassScan

    SelectionChange
    RefreshProperty
    FFormStack.RefreshAll

  ENDIF

  'STOP

END


PUBLIC SUB CopySelection()

  DIM hCtrl AS CControl

  IF Selection.Count = 0 THEN RETURN

  ResetSave

  $iSaveX = Master.GetProperty("X")
  $iSaveY = Master.GetProperty("Y")

  FOR EACH hCtrl IN Selection

    $iSaveX = Min($iSaveX, hCtrl.GetProperty("X"))
    $iSaveY = Min($iSaveY, hCtrl.GetProperty("Y"))

  NEXT

  $bDoNotArrange = TRUE
  FOR EACH hCtrl IN Selection
    SaveOne(hCtrl)
  NEXT
  $bDoNotArrange = FALSE

  Clipboard.Copy($sSave, FORM_CLIPBOARD_FORMAT)

  $iSaveX = 0
  $iSaveY = 0

END


FUNCTION CanPaste() AS Boolean

  RETURN Clipboard.Format = FORM_CLIPBOARD_FORMAT

END


PUBLIC SUB PasteSelection()

  DIM hParent AS CControl
  DIM sData AS String

  sData = Clipboard.Paste(FORM_CLIPBOARD_FORMAT)
  IF NOT sData THEN RETURN

  IF Selection.Count = 1 THEN
    hParent = Master
  ELSE IF Selection.Count > 1 THEN
    hParent = Master.Parent
  ELSE
    hParent = Control[Name]
  ENDIF

  IF NOT hParent.IsContainer() THEN
    hParent = hParent.Parent
  ENDIF

  UnSelectAll

  'PRINT Clipboard.Text
  $bSelectNew = TRUE
  FromString(sData, hParent)
  $bSelectNew = FALSE

  RefreshProperty
  FFormStack.RefreshAll

END



PRIVATE SUB RefreshProperty(OPTIONAL bForce AS Boolean)

  IF $bSelChange OR bForce THEN
    RefreshMenu
    FProperty.RefreshAll
    $bSelChange = FALSE
  ENDIF

END


PUBLIC SUB Modify(OPTIONAL bReset AS Boolean)

  DIM hEditor AS FEditor

  IF Project.ReadOnly THEN RETURN
  IF $bDoNotModify THEN RETURN

  IF $bModify <> bReset THEN RETURN

  $bModify = NOT bReset
  DrawTitle

  IF $bModify THEN
    hEditor = GetEditor()
    IF hEditor THEN hEditor.Scan = NULL
  ENDIF

END


PUBLIC FUNCTION IsModified() AS Boolean

  RETURN $bModify

END


PRIVATE SUB DrawTitle()

  DIM sTitle AS String

  sTitle = File.Name(Path)
  IF $bModify THEN sTitle = sTitle & " [" & ("modified") & "]"
  ME.Title = sTitle '& " - " & Project.Name

END



PRIVATE SUB DoRaise()

  DIM hCtrl AS CControl

  FOR EACH hCtrl IN Selection
    hCtrl.Raise
  NEXT

  FFormStack.RefreshAll

END


PUBLIC SUB DoLower()

  DIM hCtrl AS CControl

  FOR EACH hCtrl IN Selection
    hCtrl.Lower
  NEXT

  FFormStack.RefreshAll

END


PRIVATE FUNCTION GetSortKey(hCtrl AS Control, iArr AS Integer) AS String

  DIM sKey AS String

  SELECT CASE iArr

    CASE Arrange.Horizontal
      sKey = Format(hCtrl.X, "000000") & Format(hCtrl.W, "000000")
    CASE Arrange.Vertical
      sKey = Format(hCtrl.Y, "000000") & Format(hCtrl.H, "000000")
    CASE Arrange.TopBottom
      sKey = Format(hCtrl.X, "000000") & Format(hCtrl.Y, "000000") & Format(hCtrl.W, "000000") & Format(hCtrl.H, "000000")
    CASE Arrange.LeftRight
      sKey = Format(hCtrl.Y, "000000") & Format(hCtrl.X, "000000") & Format(hCtrl.H, "000000") & Format(hCtrl.W, "000000")

  END SELECT

  RETURN sKey

END


PRIVATE SUB ArrangeContainer(hParent AS Container, iArr AS Integer, OPTIONAL bRec AS Boolean = TRUE)

  DIM X AS Integer
  DIM Y AS Integer
  DIM aPos AS NEW String[]
  DIM sPos AS String
  DIM hCtrl AS Control
  DIM hCCtrl AS CControl
  DIM hCont AS Container
  DIM aCtrl AS NEW Object[]

  IF hParent THEN
    FOR EACH hCtrl IN hParent.Children
      IF hCtrl.Tag THEN aCtrl.Add(hCtrl)
    NEXT
  ELSE IF Selection.Count >= 2 THEN
    FOR EACH hCCtrl IN Selection
      aCtrl.Add(hCCtrl.Control)
    NEXT
  ELSE
    ArrangeContainer(Control[Name].Control, iArr)
    RETURN
  ENDIF

  IF aCtrl.Count = 0 THEN RETURN

  FOR EACH hCtrl IN aCtrl
    IF bRec THEN
      TRY hCont = hCtrl
      IF NOT ERROR THEN
        ArrangeContainer(hCtrl, iArr)
      ENDIF
    ENDIF
    aPos.Add(GetSortKey(hCtrl, iArr))
  NEXT

  IF aPos.Count = 0 THEN RETURN

  aPos.Sort(gb.Descent)

  FOR EACH sPos IN aPos
    FOR EACH hCtrl IN aCtrl
      IF GetSortKey(hCtrl, iArr) = sPos THEN
        hCtrl.Lower
        BREAK
      ENDIF
    NEXT
  NEXT

  FFormStack.RefreshAll

  Modify

END



PUBLIC SUB mnuSave_Click()

  Save

END



PRIVATE SUB ResetSave()

  $sSave = ""
  $iSaveX = 0
  $iSaveY = 0
  '$iIndent  = 0
  $iSaveLevel = 0

END


PRIVATE FUNCTION GetEditor() AS FEditor

  DIM sPath AS String

  sPath = File.Dir(Path) &/ File.BaseName(Path) & ".class"
  RETURN Project.Files[sPath]

END


PRIVATE SUB GotoEventMethod(hCtrl AS CControl, sEvent AS String)

  DIM sPath AS String
  DIM sGroup AS String

  IF NOT hCtrl THEN hCtrl = Control[Name]

  sPath = File.Dir(Path) &/ File.BaseName(Path) & ".class"

  IF hCtrl.Kind = "Form" THEN
    sGroup = "Form"
  ELSE
    sGroup = hCtrl.GetGroup()
  ENDIF

  Project.OpenFile(sPath)

  Project.Files[sPath].GotoEvent(sGroup, sEvent,
    FExplorer.TransformSignature(CComponent.Classes[$sType &/ hCtrl.Kind].Symbols[":" & sEvent].Signature, FALSE))

END


PUBLIC SUB Control_DblClick()

  DIM sEvent AS String
  DIM hCurrent AS CControl
  DIM sGroup AS String

  hCurrent = Control[LAST.Tag]

  sEvent = CComponent.Classes[$sType &/ hCurrent.Kind].DefaultEvent
  IF NOT sEvent THEN RETURN

  GotoEventMethod(hCurrent, sEvent)

END


PUBLIC SUB Menu_Click()
 
  Control_DblClick

END


PRIVATE SUB CreateMenu()

  DIM hCtrl AS CControl
  DIM hMenu AS Menu
  DIM cCtrl AS NEW String[]
  DIM sName AS String
  DIM cSymbol AS Collection
  DIM hSymbol AS CSymbolInfo
  DIM sGroup AS String

  mnuSelect.Children.Clear

  FOR EACH hCtrl IN Control
    sName = hCtrl.Name
    IF sName <> Name THEN
      IF hCtrl.Kind <> "Menu" THEN
        cCtrl.Add(sName)
      ENDIF
    ENDIF
  NEXT

  mnuSelect.Enabled = cCtrl.Count

  cCtrl.Sort(gb.Text)

  FOR EACH sName IN cCtrl

    hMenu = NEW Menu(mnuSelect) AS "mnuControl"
    hMenu.Text = sName

  NEXT

  mnuEvent.Visible = FALSE

  IF NOT $bReadOnly THEN

    IF Master THEN
      cCtrl = CComponent.Classes[$sType &/ Master.Kind].Events
      sGroup = Master.GetGroup()
    ELSE
      cCtrl = CComponent.Classes[$sType &/ "Form"].Events
      sGroup = "Form"
    ENDIF

    IF cCtrl THEN

      mnuEvent.Children.Clear
      cSymbol = CComponent.GetClassSymbols(Name)

      FOR EACH sName IN cCtrl

        hMenu = NEW Menu(mnuEvent) AS "mnuEvent"
        hMenu.Text = sName

        hSymbol = cSymbol[sGroup & "_" & sName]
        IF hSymbol THEN
          IF hSymbol.Kind = "m" THEN hMenu.Checked = TRUE
        ENDIF

      NEXT

      mnuEvent.Visible = TRUE

    ENDIF

  ENDIF

  RefreshMenu

END


SUB RefreshMenu()

  DIM bOn AS Boolean

  bOn = NOT IsNull(Master)

  Action[".cut", ME].Enabled = bOn
  Action[".copy", ME].Enabled = bOn
  Action[".delete", ME].Enabled = bOn
  Action[".lower", ME].Enabled = bOn
  Action[".raise", ME].Enabled = bOn

  bOn = Selection.Count >= 2

  mnuAlign.Enabled = bOn
  Action[".align-*", ME].Enabled = bOn
  Action[".same-*", ME].Enabled = bOn
  Action["paste-form"].Enabled = CanPaste()
  
  mnuArrange.Visible = NOT $bReadOnly
  mnuAlign.Visible = NOT $bReadOnly  
  Action[".save,.refresh,.cut,paste-form,.delete,.lower,.raise,.align*,.same*,.menu,.arrange*", ME].Visible = NOT $bReadOnly

END


SUB SelectionChange()

  $bSelChange = TRUE
  RefreshMenu

END



PUBLIC SUB mnuControl_Click()

  UnselectAll
  Control[LAST.Text].Select(ME, TRUE)
  RefreshProperty

END


PUBLIC SUB mnuEvent_Click()

  GotoEventMethod(Master, LAST.Text)

END


PUBLIC SUB Rename(sNewName AS String, sNewPath AS String)

  DIM hCtrl AS CControl

  hCtrl = Control[Name]

  Name = sNewName
  Path = sNewPath 'File.Dir(Path) &/ sNewName & "." & File.Ext(Path)

  hCtrl.Rename(sNewName)

  Modify
  ME.Save

  DrawTitle

END

PUBLIC SUB mnuShowProperty_Click()

  FProperty.Show

END


PUBLIC SUB mnuShowCode_Click()

  Project.OpenFile(Name)

END


PUBLIC SUB Control_Draw(OPTIONAL iIndex AS Integer)

  'DIM hForm AS Form
  DIM X AS Integer
  DIM Y AS Integer
  DIM SX AS Integer
  DIM SY AS Integer
  DIM SXF AS Integer
  DIM SYF AS Integer
  DIM iMod AS Integer
  DIM DX AS Integer
  DIM DY AS Integer
  DIM hPict AS Picture
  'DIM hGrid AS Picture

  IF LAST.Tag <> Name THEN

    hPict = Picture["img/control" &/ "draw-" & LCase(Control[LAST.Tag].Kind) & ".png"]
    IF NOT hPict THEN hPict = Picture["img/control" &/ LCase(Control[LAST.Tag].Kind) & ".png"]
    Draw.ForeColor = Control[Name].Control.Foreground
    IF hPict THEN
      Draw.Picture(hPict, 4, 4)
      Draw.Text(LAST.Tag, 8 + hPict.Width, 4)
    ELSE
      Draw.Text(LAST.Tag, 4, 4)
    ENDIF
    Draw.ForeColor = Color.White
    Draw.Invert = TRUE
    Draw.LineStyle = Line.Dash
    Draw.LineWidth = 2
    Draw.Rect(1, 1, LAST.W - 1, LAST.H - 1)
    RETURN

  ENDIF

  IF NOT Project.ShowGrid THEN RETURN

  'hForm = LAST.Parent

  'IF hForm.Picture THEN
  '  Draw.Picture(hForm.Picture, 0, 0)
  'ENDIF

  'PRINT Draw.Clip.X; Draw.Clip.Y; Draw.Clip.Width; Draw.Clip.Height

  'Project.Snap = Desktop.Scale

  DX = Desktop.Scale
  WHILE (DX < 4)
    DX = DX + Desktop.Scale
  WEND

  DY = Desktop.Scale
  WHILE (DY < 4)
    DY = DY + Desktop.Scale
  WEND

'   hGrid = NEW Picture(DX, DY, TRUE)
'   Draw.Begin(hGrid)
'   Draw.ForeColor = Color.White
'   Draw.Point(0, 0)
'   Draw.End

  SX = Draw.Clip.X
  iMod = SX MOD DX
  IF iMod THEN SX = SX + DX - iMod

  SY = Draw.Clip.Y
  iMod = SY MOD DY
  IF iMod THEN SY = SY + DY - iMod

  SXF = Draw.Clip.X + Draw.Clip.Width - 1
  SYF = Draw.Clip.Y + Draw.Clip.Height - 1

  Draw.Invert = TRUE
'   Draw.Tile(hGrid, Draw.Clip.X, Draw.Clip.Y, Draw.Clip.W, Draw.Clip.H)

  Draw.ForeColor = Color.White
  FOR X = SX TO SXF STEP DX
    FOR Y = SY TO SYF STEP DY
      Draw.Point(X, Y)
    NEXT
  NEXT

END


PUBLIC SUB Refresh()

  UpdateSnap
  'Control[Name].Control.Refresh

END

' PUBLIC SUB Form_Hide()
' 
'   'DEBUG Name
'   Project.Deactivate(ME)
' 
' END


PUBLIC SUB Control_Data(Row AS Integer, Column AS Integer)

  IF Row = 0 AND Column = 0 THEN
    LAST.Data.Text = Control[LAST.Tag].Name
    'LAST.Data.Picture = Picture["img/16/image.png"]
  ENDIF

END


PUBLIC SUB mnuSelectAll_Click()

  DIM hChild AS Control
  DIM hCtrl AS CControl
  DIM bFirst AS Boolean

  UnselectAll
  bFirst = TRUE

  FOR EACH hChild IN Control[Name].Control.Children

    hCtrl = Control[hChild.Tag]

    IF IsNull(hCtrl) THEN CONTINUE 'panel

    hCtrl.Select(ME, bFirst)
    $bSelChange = TRUE
    bFirst = FALSE

  NEXT

  IF $bSelChange THEN
    SelectionChange
    RefreshProperty
  ENDIF

END


PUBLIC SUB mnuUnselectAll_Click()

  UnselectAll
  RefreshProperty

END



PRIVATE SUB DoAlign(sKey AS String)

  DIM iPos AS Integer
  DIM hCtrl AS CControl

  SELECT sKey
  
    CASE ".align-top"

      iPos = Master.Control.Y
    
      FOR EACH hCtrl IN Selection
        hCtrl.Move(hCtrl.Control.X, iPos)
      NEXT
  
    CASE ".align-bottom"
      
      iPos = Master.Control.Y + Master.Control.H
    
      FOR EACH hCtrl IN Selection
        hCtrl.Move(hCtrl.Control.X, iPos - hCtrl.Control.H)
      NEXT
      
    CASE ".align-left"      
  
      iPos = Master.Control.X
    
      FOR EACH hCtrl IN Selection
        hCtrl.Move(iPos, hCtrl.Control.Y)
      NEXT
      
    CASE ".align-right"
    
      iPos = Master.Control.X + Master.Control.W
    
      FOR EACH hCtrl IN Selection
        hCtrl.Move(iPos - hCtrl.Control.W, hCtrl.Control.Y)
      NEXT
      
    CASE ".same-width"

      iPos = Master.Control.W
    
      FOR EACH hCtrl IN Selection
        hCtrl.Resize(iPos, hCtrl.Control.H)
      NEXT
      
    CASE ".same-height"
    
      iPos = Master.Control.H
    
      FOR EACH hCtrl IN Selection
        hCtrl.Resize(hCtrl.Control.W, iPos)
      NEXT

  END SELECT 

END


PRIVATE SUB SetReadOnly()

  $bReadOnly = Project.ReadOnly OR Project.Running
  RefreshMenu

END


PUBLIC SUB OnProjectChange()

  SetReadOnly

END

PUBLIC SUB OnProjectDebug()

  SetReadOnly

END



PUBLIC SUB Form_Open()

  'IF $bActivate THEN RETURN
  Project.SetFormIcon(ME)
  '$bActivate = TRUE

END

PUBLIC FUNCTION FindControlFromType(sType AS String) AS String[]
  
  DIM hCtrl AS CControl
  DIM aCtrl AS NEW String[]
  
  FOR EACH hCtrl IN Control
    IF hCtrl.Kind = sType THEN
      aCtrl.Add(hCtrl.Name)
    ENDIF
  NEXT  
  
  RETURN aCtrl
  
END

PRIVATE SUB MoveSelection(DX AS Integer, DY AS Integer, OPTIONAL bFree AS Boolean)

  DIM hCtrl AS CControl
  
  FOR EACH hCtrl IN Selection
    hCtrl.Move(hCtrl.Control.X + DX, hCtrl.Control.Y + DY, bFree)
  NEXT
  
END


PUBLIC SUB Form_KeyPress()

  DIM D AS Integer
  DIM bFree AS Boolean
  
  IF Key.Normal THEN
    D = Desktop.Scale
    bFree = FALSE
  ELSE IF Key.Shift AND NOT Key.Control THEN
    D = 1
    bFree = TRUE
  ELSE
    RETURN
  ENDIF 

  SELECT Key.Code
    CASE Key.Up
      MoveSelection(0, - D, bFree)
    CASE Key.Down
      MoveSelection(0, D, bFree)
    CASE Key.Left
      MoveSelection(- D, 0, bFree)
    CASE Key.Right
      MoveSelection(D, 0, bFree)        
  END SELECT

END

PUBLIC SUB UpdateBorder()

  DIM hCtrl AS CControl
  DIM H AS Integer
  
  hCtrl = Control[Name]
  IF NOT hCtrl THEN RETURN

  WITH hCtrl.Control

    IF hCtrl.GetPropertyDefault("Border") = "None" THEN
    
      panTitle.Hide
      H = 0
      panBorder.Move(0, 0, .Width + 2, .Height + 2)
      panBorder.Border = Border.Plain
      hCtrl.Control.Move(1, 1)
    
    ELSE

      H = 28 'lblTitle.Font.Height(" ") + 8
      panBorder.Move(0, H, .Width + 4, .Height + 2)
      panBorder.Border = Border.Raised
      panTitle.Resize(panBorder.W, H)
      panTitle.Show
  
      hCtrl.Control.Move(2, 0)
      
    ENDIF 
      
    panRight.Move(panBorder.W - 4, Max(0, ((.Height + H) - panRight.Height) / 2))
    panDown.Move(Max(0, (.Width - panDown.Width) / 2), panBorder.H + H - 4)
    panRightDown.Move(panRight.X, panDown.Y)
    
    'panBorder.Lower
    panRight.Raise
    panDown.Raise
    panRightDown.Raise      
    
  END WITH
  
END

PUBLIC SUB UpdateTitle()
  
  DIM hCtrl AS CControl
  DIM sPict AS String
  
  hCtrl = Control[Name]
  IF NOT hCtrl THEN RETURN

  sPict = hCtrl.GetProperty("Icon")
  IF sPict THEN
    lblTitle.Text = " " & hCtrl.GetProperty("Text")
    imgIcon.Picture = Picture["img/16/gambas.png"]
    TRY imgIcon.Picture = Image.Load(Project.Dir &/ sPict).Stretch(16, 16, TRUE).Picture
    imgIcon.Show
  ELSE
    lblTitle.Text = hCtrl.GetProperty("Text")
    imgIcon.Hide
  ENDIF

  SELECT CASE hCtrl.GetPropertyDefault("Border")
    CASE "Fixed"
      btnMaxWindow.Visible = FALSE
    CASE "Resizable"
      btnMaxWindow.Visible = TRUE
  END SELECT 
  
  UpdateBorder 
  
END



' 
' 
' PUBLIC SUB Activate(OPTIONAL hWindow AS Window)
'   
'   DIM hOld AS CWindow
'   DIM hWin AS CWindow
'   
'   IF $aWindow.Count THEN 
'   
'     IF hWindow THEN
'       TRY tabWorkspace.Index = GetIndex(hWindow)
'       RETURN
'     ENDIF
'   
'     hWin = $aWindow[tabWorkspace.Index]
'     hOld = $hCurrent
'   
'     $hCurrent = hWin
'     
'     IF $hCurrent.Resizable THEN
'       $hCurrent.Window.Move(0, 0)
'       MoveHandle
'       svwWorkspace.Raise
'     ELSE
'       panWorkspace.Raise
'     ENDIF
'     'WITH tabWorkspace
'     '  $hCurrent.Move(.X + .ClientX, .Y + .ClientY, .ClientW, .ClientH)
'     'END WITH
'     
'     WITH $hCurrent.Window
'       .Show
'       .Raise
'       .SetFocus
'     END WITH
'     
'     IF hOld AND IF hOld <> hWin THEN 
'       hOld.Window.Hide
'       'WAIT 0.2
'     ENDIF
'     
'     UpdateTitle
'     
'   ENDIF
'   
'   ME.Parent._Activate
'   
' END

' PUBLIC SUB Form_Resize()
' 
'   IF tabWorkspace.Visible THEN
'     tabWorkspace.Move(0, 0, ME.ClientW, ME.ClientH)
'     WITH tabWorkspace
'       panTitle.Move(.ClientX, .ClientY, .ClientW, panTitle.H)
'       svwWorkspace.Move(.ClientX, panTitle.H + .ClientY, .ClientW, .ClientH - panTitle.H)
'       panWorkspace.Move(.ClientX, panTitle.H + .ClientY, .ClientW, .ClientH - panTitle.H)
'     END WITH 
'     panWorkspace.BackColor = Color.Background
'   ELSE
'     svwWorkspace.Move(0, 0, ME.ClientW, ME.ClientH)
'     panWorkspace.Move(0, 0, ME.ClientW, ME.ClientH)
'     panWorkspace.BackColor = Color.Gray
'     panWorkspace.Raise
'   ENDIF
' 
' END
' 
' 
PUBLIC SUB Handle_MouseDown()

  $bMove = TRUE  
  $X = Mouse.ScreenX
  $Y = Mouse.ScreenY
  $W = Control[Name].Control.W
  $H = Control[Name].Control.H
  
  'DEBUG Mouse.ScreenX;; Mouse.ScreenY
  'DEBUG $X;; $Y

END

PUBLIC SUB Handle_MouseMove()

  DIM W, H, G AS Integer
  DIM hPanel AS Panel

  IF NOT $bMove THEN RETURN
  
  hPanel = LAST

  WITH Control[Name].Control

    W = .W
    H = .H

    'DEBUG "(";; W;; H;; ") + (";; Mouse.ScreenX;; Mouse.ScreenY;; ") -> ";

    IF hPanel <> panRight THEN H = $H + Mouse.ScreenY - $Y
    IF hPanel <> panDown THEN W = $W + Mouse.ScreenX - $X
    
    W = Max(1, W)
    H = Max(1, H)

    IF NOT Mouse.Shift THEN    
      G = Project.Snap
      IF G THEN
        W = Max(1, Int(W / G + 0.5)) * G
        H = Max(1, Int(H / G + 0.5)) * G
      ENDIF
    ENDIF 
    
    'PRINT #File.Err, "(";; W;; H;; ")"
    
    .Resize(W, H)
  
  END WITH
  
  '$bMove = FALSE
  'UpdateBorder
  '$bMove = TRUE

END

PUBLIC SUB Handle_MouseUp()

  $bMove = FALSE  

END


PUBLIC SUB Action_Activate(Key AS String) AS Boolean
  
  SELECT CASE Key
  
    CASE ".menu"
      FMenu.Run(ME)
  
    CASE ".delete"
      DeleteSelection
    
    CASE ".copy"
      CopySelection
      UnSelectAll
    
    CASE "paste-form"
      PasteSelection

    CASE ".cut"
      CopySelection
      DeleteSelection
      
    CASE ".align-left", ".align-right", ".align-top", ".align-bottom", ".same-width", ".same-height"
      DoAlign(Key)
      
    CASE ".arrange-horizontal"
      ArrangeContainer(NULL, Arrange.Horizontal)

    CASE ".arrange-vertical"
      ArrangeContainer(NULL, Arrange.Vertical)

    CASE ".arrange-row"
      ArrangeContainer(NULL, Arrange.Row)

    CASE ".arrange-column"
      ArrangeContainer(NULL, Arrange.Column)
      
    CASE ".raise"
      DoRaise
      
    CASE ".lower"
      DoLower

    DEFAULT 
      RETURN TRUE
      
  END SELECT 
  
END

PUBLIC SUB Form_Activate()

  mnuForm.Enabled = TRUE

END

PUBLIC SUB Form_Deactivate()

  mnuForm.Enabled = FALSE

END


More information about the User mailing list