﻿#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Outfile=ResizeAndDock.exe
#AutoIt3Wrapper_UseUpx=y
#AutoIt3Wrapper_Res_Description=Simplify and enhance docking features
#AutoIt3Wrapper_Res_Fileversion=1.0.0.0
#AutoIt3Wrapper_Res_LegalCopyright=Bert Kerkhof 2019-11-25 Apache 2.0 license
#AutoIt3Wrapper_Res_SaveSource=n
#AutoIt3Wrapper_AU3Check_Parameters=-d -w 3 -w 4 -w 5
#AutoIt3Wrapper_Run_Tidy=y
#Tidy_Parameters=/tc 2 /reel
#AutoIt3Wrapper_Run_Au3Stripper=y
#Au3Stripper_Parameters=/sf /sv /rm
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

#include-once
#include <ComboConstants.au3>; Delivered With AutoIt
#include <GuiRichEdit.au3>; Delivered With AutoIT
#include <aDrosteArray.au3>; Published at GitHub

; Author: Bert Kerkhof ( kerkhof.bert@gmail.com )
; Tested with AutoIT v3.3.14.5 interpreter/compiler and win10

;
; Notes on the use of the RichEdit control:
;
; The RichEdit control delivered with the AutoIT package,
; originated as an external component. Today the
; integration of the control in the AutoIT gui family is
; not finished yet.
;
; One of the issues is resizing the control. With this demo,
; the RichEdit controls will resize together with the Gui.
; To enbable resize, set the style field of the GuiCreate call.
;
; Have programming succes with the GuiRichExtra module,
;
;     kerkhof.bert@gmail.com

;
; Dock system =========================================================

Global $ActH = Array($GUI_DOCKLEFT, $GUI_DOCKRIGHT, $GUI_DOCKHCENTER)
Global $ActV = Array($GUI_DOCKTOP, $GUI_DOCKBOTTOM, $GUI_DOCKVCENTER)
Global $ActHV = Array($ActH, $ActV)

Global $DOCK_XSTRETCH = $GUI_DOCKLEFT + $GUI_DOCKRIGHT
Global $DOCK_YSTRETCH = $GUI_DOCKTOP + $GUI_DOCKBOTTOM
Global $DOCK_XUPPER = $GUI_DOCKLEFT + $GUI_DOCKWIDTH
Global $DOCK_YUPPER = $GUI_DOCKTOP + $GUI_DOCKHEIGHT
Global $DOCK_XLOWER = $GUI_DOCKRIGHT + $GUI_DOCKWIDTH
Global $DOCK_YLOWER = $GUI_DOCKBOTTOM + $GUI_DOCKHEIGHT
Global $DOCK_XABOVEMID = $GUI_DOCKHCENTER + $GUI_DOCKLEFT
Global $DOCK_YABOVEMID = $GUI_DOCKVCENTER + $GUI_DOCKTOP
Global $DOCK_XBENEATHMID = $GUI_DOCKHCENTER + $GUI_DOCKRIGHT
Global $DOCK_YBENEATHMID = $GUI_DOCKVCENTER + $GUI_DOCKBOTTOM
Global $DOCK_XMID = $GUI_DOCKHCENTER + $GUI_DOCKWIDTH
Global $DOCK_YMID = $GUI_DOCKVCENTER + $GUI_DOCKHEIGHT

; #FUNCTION#
; Name ..........: _ActMetric
; Description ...: Deliver gui client area coordinates
; Syntax ........: _ActMetric($idGui, $idRich)
; Parameters ....: $idGui .... Main gui control handle
;                  $idRich ... External component handle
; Return values .: 2x4 dim droste array of gui sizes
; Author ........: Bert Kerkhof

Func _ActMetric($idGui, $idRich)
  Local $A = aDroste(WinGetPos($idGui))
  Local $S = aDroste(WinGetClientSize($idGui))
  ; Calculate window client area, exclude height of menu's:
  ; additional correction +8 in WS_SIZEBOX gui measure
  ; is tested with AutoIT v3.3.14.5 and win10.
  $A = Array($A[1] + 8, $A[2] + $A[4] - $S[2] - 8, $S[1], $S[2])  ; ltwh format
  Local $B = aDroste(WinGetPos($idRich)) ; ltwh
  Local $H = Array($A[1], $B[1], $B[1] + $B[3], $A[1] + $A[3])   ; Horizontal range
  Local $V = Array($A[2], $B[2], $B[2] + $B[4], $A[2] + $A[4])   ; Vertical
  Return Array($H, $V)
EndFunc   ;==>_ActMetric

; #FUNCTION#
; Name ..........: _ActResize
; Description ...: Resize external gui component with docking
; Syntax ........: _ActResize($idGui, $idRich, $nDock)
; Parameters ....: $idGui .... Main gui control handle
;                  $idRich ... External component handle
;                  $nDock .... Resizing method selector.
; Return values .: None
; Author ........: Bert Kerkhof
; Remark ........: Docking description: see the AutoIT helpfile,
;                  item: GuiCtrlSetResizing

Global $ActMetric = aNew() ; metric at program start
Func _ActResize($idGui, $idRich, $nDock)
  Local $Q = aNew(), $aaC = $ActMetric ; constants
  Local $aaP = _ActMetric($idGui, $idRich) ; current metric
  If $nDock = $GUI_DOCKAUTO Then $nDock = $GUI_DOCKBORDERS
  For $I = 1 To 2 ; horizontal, vertical
    Local $C = $aaC[$I], $P = $aaP[$I], $aDock = $ActHV[$I]
    Select
      Case BitAND($nDock, $aDock[1]) And BitAND($nDock, $aDock[2])
        ; left+right, top+bottom:
        $P[3] = $P[4] - $C[4] + $C[3]
        $P[2] = $C[2]
      Case BitAND($nDock, $aDock[1]) ; left, top:
        If BitAND($nDock, $aDock[3]) Then ; hcenter, vcenter:
          $P[3] = Round($C[3] - ($C[4] - $C[1]) / 2 + ($P[4] - $C[1]) / 2)
          $P[2] = $C[2]
        Else
          $P[2] = $C[2]
          $P[3] = $C[3] ; assume width
        EndIf
      Case BitAND($nDock, $aDock[2]) ; right, bottom:
        If BitAND($nDock, $aDock[3]) Then ; hcenter, vcenter:
          $P[3] = $P[4] - $C[4] + $C[3]
          $P[2] = Round($C[2] - ($C[4] - $C[1]) / 2 + ($P[4] - $C[1]) / 2)
        Else
          $P[3] = $P[4] - $C[4] + $C[3] ; assume width
          $P[2] = $P[3] + $C[2] - $C[3]
        EndIf
      Case BitAND($nDock, $aDock[3]) ; hcenter, vcenter:
        $P[2] = Round($C[2] + 0.5 * ($P[4] - $C[4]))
        $P[3] = $P[2] + $C[3] - $C[2] ; assume width
    EndSelect
    $Q[$I] = $P
  Next
  ; Adaptation to winmove (same as _winapi_movewindow):
  Local $nL = ($Q[1])[2] - ($aaC[1])[1], $nT = ($Q[2])[2] - ($aaC[2])[1]
  WinMove($idRich, "", $nL, $nT, ($Q[1])[3] - ($Q[1])[2], ($Q[2])[3] - ($Q[2])[2])
EndFunc   ;==>_ActResize

;
; Demo ================================================================

Func Sizebox()
  Local $aDock = Array($DOCK_XSTRETCH + $DOCK_YSTRETCH)
  aAdd($aDock, $DOCK_XUPPER + $DOCK_YUPPER)
  aAdd($aDock, $DOCK_XLOWER + $DOCK_YLOWER)
  aAdd($aDock, $DOCK_XABOVEMID + $DOCK_YABOVEMID)
  aAdd($aDock, $DOCK_XBENEATHMID + $DOCK_YBENEATHMID)
  aAdd($aDock, $DOCK_XMID + $DOCK_YMID)
  Local $aLabel = Array("Stretch", "Upper", "Lower", "AboveMid", "BeneathMid", "Mid")
  Local $nDock = 1, $Msg, $cStyle = $CBS_DROPDOWN + $CBS_AUTOHSCROLL
  While True
    Local $idGui = GUICreate("SizeBox", 400, 240, 160, 160, $WS_SIZEBOX)
    Local $idCombo = GUICtrlCreateCombo($aLabel[$nDock], 5, 5, 80, 20, $cStyle)
    GUICtrlSetData(-1, sRecite($aLabel))
    GUICtrlSetResizing(-1, $DOCK_XUPPER + $DOCK_YUPPER)
    Local $idTab = GUICtrlCreateTab(55, 40, 340, 170)
    Local $idRich = _GUICtrlRichEdit_Create($idGui, "", 57, 44, 335, 164)
    _GUICtrlRichEdit_SetBkColor($idRich, 0xC6FFFB) ; SoftYellow
    _GUICtrlRichEdit_AppendText($idRich, "Drag gui border to test docking" & @LF & _
        "of the yellow richedit control." & @LF & @LF & _
        "An internal component to compare " & @LF & _
        "is drawn in the background in white.")
    GUICtrlSetResizing($idTab, $aDock[$nDock])
    $ActMetric = _ActMetric($idGui, $idRich) ; Set global variable
    GUISetState() ; Show
    While True
      $Msg = GUIGetMsg()
      Switch $Msg
        Case $idCombo
          $nDock = aSearch($aLabel, GUICtrlRead($idCombo))
          ExitLoop
        Case $GUI_EVENT_RESIZED, $GUI_EVENT_RESTORE, $GUI_EVENT_MAXIMIZE
          _ActResize($idGui, $idRich, $aDock[$nDock])
        Case $GUI_EVENT_CLOSE
          ExitLoop
      EndSwitch
    WEnd
    If $Msg = $GUI_EVENT_CLOSE Then ExitLoop
    GUIDelete($idGui)
  WEnd
EndFunc   ;==>Sizebox
Sizebox()

; End =================================================================
