Page 1 of 2

Nueva clase TLayout

PostPosted: Sun Sep 22, 2013 6:43 pm
by Daniel Garcia-Gil
Saludos,

les dejo una nueva clase para crear layout en ventanas, esto nos permite autoajustar los controles contenidos, con esta clase podriamos olvidar el uso de @ x,y y el tamaño de los controles

para ver el efecto redimencionen la ventana

dejo un zip con 2 ejemplos ejecutable y todas las fuentes

http://sitasoft.net/fivewin/samples/layout_1.zip

para correr los ejemplos por favor copiarlos en la carpeta de samples de fivewin

aqui el codigo de uno de los ejemplos

Code: Select all  Expand view

#include "fivewin.ch"
#include "ribbon.ch"
#include "gif.ch"


function main()
    local oWnd
    local oMainLay
    local hLays := {=>}
    local hButtons := {=>}
    local hBrowses := {=>}
    local oRBar, oFld

    define window oWnd title "testing layout"


    USE CUSTOMER NEW SHARED ALIAS "CUST1"
    USE CUSTOMER NEW SHARED ALIAS "CUST2"

    hLays["MAIN"] = TLayout():new( oWnd )

    hLays["H1"] = hLays["MAIN"]:addHLayout(75)
    hLays["H2"] = hLays["MAIN"]:addHLayout()

    //add 4 layout in H1, will use for 4 buttons
    hLays["H1"]:addVLayout()
    hLays["H1"]:addVLayout()
    hLays["H1"]:addVLayout()
    hLays["H1"]:addVLayout()

    @ 0,0 button hButtons["ONE"] prompt "btn1" of hLays["H1"]:aVLayout[1]
    hLays["H1"]:aVLayout[1]:oClient = hButtons["ONE"]

    @ 0,0 button hButtons["TWO"] prompt "btn2" of hLays["H1"]:aVLayout[2]
    hLays["H1"]:aVLayout[2]:oClient = hButtons["TWO"]

    @ 0,0 button hButtons["THREE"] prompt "btn3" of hLays["H1"]:aVLayout[3]
    hLays["H1"]:aVLayout[3]:oClient = hButtons["THREE"]

    @ 0,0 button hButtons["FOUR"] prompt "btn4" of hLays["H1"]:aVLayout[4]
    hLays["H1"]:aVLayout[4]:oClient = hButtons["FOUR"]

/*
IN THIS POINT THE DISTRIBUTION IS
----------------------------------
|     |                          |
|btn1 |                          |
|-----|                          |
|     |                          |
|btn2 |                          |
|-----|                          |
|     |                          |
|btn3 |                          |
|-----|                          |
|     |                          |
|btn4 |                          |
----------------------------------
->75<-|->REST OF WIDTH         <-|
*/

   
    //add 3 layout in H2, will use for 3 xbrowse
    hLays["H2"]:addVLayout()
    hLays["H2"]:addVLayout()
    hLays["H2"]:addVLayout()


    @ 0,0 XBROWSE hBrowses["ONE"] OF hLays["H2"]:aVLayout[1] ALIAS "CUST1"
    hBrowses["ONE"]:CreateFromCode()
    hLays["H2"]:aVLayout[1]:oClient = hBrowses["ONE"]

   
    @ 0, 0 FOLDEREX oFld PIXEL PROMPT "Gifs", "xbrowse", "layout" of hLays["H2"]:aVLayout[2]
    hLays["H2"]:aVLayout[2]:oClient = oFld

    @ 1,   1 GIF FILE "..\gifs\matrix4.gif" OF oFld:aDialogs[ 1 ]

    @ 0,0 XBROWSE hBrowses["ONE"] OF oFld:aDialogs[2] ALIAS "CUST2"
    hBrowses["ONE"]:CreateFromCode()
    oFld:aDialogs[2]:oClient = hBrowses["ONE"]

    //WORKING INSIDE FOLDERS
    hLays["FOLDER"] = TLayout():new( oFld:aDialogs[3] )

    hLays["FOLDER_H1"] = hLays["FOLDER"]:addHLayout()

    //add 4 layout in FOLDER_H1, will use for 4 buttons
    hLays["FOLDER_H1"]:addVLayout()
    hLays["FOLDER_H1"]:addVLayout()
    hLays["FOLDER_H1"]:addVLayout()
    hLays["FOLDER_H1"]:addVLayout()

    @ 0,0 button hButtons["FOLDER_ONE"] prompt "btn1" of hLays["FOLDER_H1"]:aVLayout[1]
    hLays["FOLDER_H1"]:aVLayout[1]:oClient = hButtons["FOLDER_ONE"]

    @ 0,0 button hButtons["FOLDER_TWO"] prompt "btn2" of hLays["FOLDER_H1"]:aVLayout[2]
    hLays["FOLDER_H1"]:aVLayout[2]:oClient = hButtons["FOLDER_TWO"]

    @ 0,0 button hButtons["FOLDER_THREE"] prompt "btn3" of hLays["FOLDER_H1"]:aVLayout[3]
    hLays["FOLDER_H1"]:aVLayout[3]:oClient = hButtons["FOLDER_THREE"]

    @ 0,0 button hButtons["FOLDER_FOUR"] prompt "btn4" of hLays["FOLDER_H1"]:aVLayout[4]
    hLays["FOLDER_H1"]:aVLayout[4]:oClient = hButtons["FOLDER_FOUR"]




    DEFINE RIBBONBAR oRBar WINDOW  hLays["H2"]:aVLayout[3] PROMPT "One", "Two", "Three" HEIGHT 133 TOPMARGIN 25 2010

/*
IN THIS POINT THE DISTRIBUTION IS
----------------------------------
|     |                          |
|btn1 |                          |
|-----| xbrowse                  |
|     |--------------------------|
|btn2 |                          |
|-----|                          |
|     | folderex                 |
|btn3 |--------------------------|
|-----|                          |
|     |                          |
|btn4 | ribbonbar                |
----------------------------------
->75<-|->REST OF WIDTH         <-|
*/


    activate window oWnd

return nil
 


Code: Select all  Expand view


#include "fivewin.ch"

#define LAYOUT_TYPE_MAIN       0
#define LAYOUT_TYPE_HORIZONTAL 1
#define LAYOUT_TYPE_VERTICAL   2


class TLayout from TPanel
   
    data bOnResize
    data aHLayout, aVLayout
    data nType
    data nTop, nLeft, nWidth, nHeight
    data lFixed

    data nSumHFix, nHFix, nSumVFix, nVFix HIDDEN

    method new( oWnd )
    method addHLayout()
    method addVLayout()

    method calculeHorizontal( nWidth, nHeight ) HIDDEN
    method calculeVertical( nWidth, nHeight ) HIDDEN

    method onResized( nWidth, nHeight )


endclass


//----------------------------------------------------//

method TLayout:new( oWnd )

    local bOnResize

    ::aHLayout  = {}
    ::aVLayout  = {}

    ::nTop      = 0
    ::nLeft     = 0
    ::nWidth    = 0
    ::nHeight   = 0

    ::lFixed  = .F.
    ::nSumHFix = 0
    ::nHFix    = 0 
    ::nSumVFix = 0
    ::nVFix    = 0

    ::nId = ::GetNewId()

    ::bOnResize = oWnd:bResized

    oWnd:bResized = {| nType, nWidth, nHeight | ::onResized( nType, nWidth, nHeight ) }

    if ! oWnd:isKindOf("TLAYOUT")
        ::nType = LAYOUT_TYPE_MAIN
        oWnd:oClient = self
    endif

return ::Super:new(0,0, oWnd:nHeight, oWnd:nWidth, oWnd)

//----------------------------------------------------//

method TLayout:addVLayout( nHeight )

    local oChild

    DEFAULT nHeight := 0

    oChild = TLayout():new( self )

    oChild:nType = LAYOUT_TYPE_VERTICAL
    oChild:lFixed = nHeight > 0
    oChild:nHeight = nHeight
   
    if oChild:lFixed
        ::nSumVFix++
        ::nVFix += nHeight
    endif

    aadd( ::aVLayout, oChild )

return oChild

//----------------------------------------------------//

method TLayout:addHLayout( nWidth )

    local oChild

    DEFAULT nWidth := 0

    oChild = TLayout():new( self )

    oChild:nType = LAYOUT_TYPE_HORIZONTAL
    oChild:lFixed = nWidth > 0
    oChild:nWidth = nWidth
   
    if oChild:lFixed
        ::nSumHFix++
        ::nHFix += nWidth
    endif

    aadd( ::aHLayout, oChild )

return oChild

//----------------------------------------------------//

method TLayout:calculeVertical( nWidth, nHeight )
    local nLen
    local nNewHeight
    local nAuxHeight, nCalcHeight
    local nItem, nCountNotFixed := 0
    local nTop, nLeft
    local oItem
    local nAcum := 0

    nLen = Len( ::oWnd:aVLayout )
    nCalcHeight := ( nHeight - ::oWnd:nVFix ) / Max( 1, ( nLen - ::oWnd:nSumVFix ) )
    nNewHeight = nCalcHeight
    nTop = 0
    nLeft = 0
    for nItem = 1 to nLen
        oItem = ::oWnd:aVLayout[ nItem ]
        if oItem:nId == ::nId
            if oItem:lFixed
                nAuxHeight = nNewHeight
                nNewHeight = oItem:nHeight
            else
                nCountNotFixed++
                nNewHeight = Round( nCalcHeight * nCountNotFixed, 0 ) - nAcum
                nAuxHeight = nNewHeight
            endif
            ::Move( nTop, nLeft, nWidth, nNewHeight )
            nNewHeight = nAuxHeight                                            
            exit
        else
            if oItem:lFixed
                nTop += oItem:nHeight
            else
                nCountNotFixed++
                nNewHeight = Round( nCalcHeight * nCountNotFixed, 0 ) - nAcum
                nAcum += nNewHeight
                nTop += nNewHeight
            endif          
        endif   
    next
return nil

//----------------------------------------------------//

method TLayout:calculeHorizontal( nWidth, nHeight )
    local nLen
    local nNewWidth
    local nAuxWidth, nCalcWidth
    local nItem, nCountNotFixed := 0
    local nTop, nLeft
    local oItem
    local nAcum := 0

    nLen = Len( ::oWnd:aHLayout )
    nCalcWidth := ( nWidth - ::oWnd:nHFix ) / Max( 1, ( nLen - ::oWnd:nSumHFix ) )
    nNewWidth = nCalcWidth
    nTop = 0
    nLeft = 0
    for nItem = 1 to nLen
        oItem = ::oWnd:aHLayout[ nItem ]
        if oItem:nId == ::nId
            if oItem:lFixed
                nAuxWidth = nNewWidth
                nNewWidth = oItem:nWidth
            else
                nCountNotFixed++
                nNewWidth = Round( nCalcWidth * nCountNotFixed, 0 ) - nAcum
                nAuxWidth = nNewWidth
            endif
            ::Move( nTop, nLeft, nNewWidth, nHeight )
            nNewWidth = nAuxWidth                                              
            exit
        else
            if oItem:lFixed
                nLeft += oItem:nWidth
            else
                nCountNotFixed++
                nNewWidth = Round( nCalcWidth * nCountNotFixed, 0 ) - nAcum
                nAcum += nNewWidth
                nLeft += nNewWidth
            endif          
        endif   
    next
return nil

//----------------------------------------------------//

method TLayout:onResized( nType, nWidth, nHeight )
    if ::nType != LAYOUT_TYPE_MAIN
        if ::oWnd:isKindOf( "TLAYOUT" )
            switch ::nType
                case LAYOUT_TYPE_HORIZONTAL
                    ::calculeHorizontal( nWidth, nHeight )
                    exit
                case LAYOUT_TYPE_VERTICAL
                    ::calculeVertical( nWidth, nHeight )
                    exit
            endswitch
        endif
    end

    if ! ( ::bOnResize == NIL )
        Eval( ::bOnResize, nType, nWidth, nHeight )
    endif

return 0


//----------------------------------------------------//

 


Image
Image
Image
Image

Re: Nueva clase TLayout

PostPosted: Sun Sep 22, 2013 6:57 pm
by pablovidal
EXELENTE APORTACION !!! GRACIAS DANIEL

:) :) :) :) :lol: :lol: :lol: :) :) :)

Re: Nueva clase TLayout

PostPosted: Sun Sep 22, 2013 10:25 pm
by horacio
Excelente, era una funcionalidad que faltaba en FWH. Gracias Daniel !!!

Re: Nueva clase TLayout

PostPosted: Mon Sep 23, 2013 1:11 am
by El Loco
Espectacular !!!
Daniel gracias por este gran aporte !!!

Un gran abrazo

Re: Nueva clase TLayout

PostPosted: Mon Sep 23, 2013 2:43 pm
by Adolfo
Oooooooooooooooooooooooooooooooooooooooooooooooh
Fantastico..

Arreglo mis ventanas de venta inmediatamente, con esto me despreocupo de la resolucion de los monitores...

Buena.

Re: Nueva clase TLayout

PostPosted: Mon Sep 23, 2013 2:54 pm
by acuellar
Excelente, Gracias Daniel

Saludos,

Adhemar

Re: Nueva clase TLayout

PostPosted: Mon Sep 23, 2013 2:55 pm
by Antonio Linares
Solo nuestro querido mago de los números (y de muchas mas cosas) podia hacer una clase tan buena :-)

Gracias!

Re: Nueva clase TLayout

PostPosted: Mon Sep 23, 2013 10:41 pm
by sysctrl2
Oraleeee !!
como siempre Maestro Daniel,
Felicidades !!

Re: Nueva clase TLayout

PostPosted: Mon Sep 23, 2013 11:59 pm
by devtuxtla
Daniel.

FANTASTICO

Gracias

Saludos

Re: Nueva clase TLayout

PostPosted: Tue Sep 24, 2013 3:15 am
by AIDA
Super increíble genio ! :shock:


Saluditos :wink:

Re: Nueva clase TLayout

PostPosted: Tue Sep 24, 2013 11:22 am
by MarioG
Daniel;
como siempre muchisimas gracias por tu nuevo y desinteresado aporte

Re: Nueva clase TLayout

PostPosted: Tue Sep 24, 2013 1:29 pm
by George
Daniel,
Muchas gracias.
Este es un aporte de primera magnitud que aumenta el nivel de profesionalismo de los programas desarrollados con FWH.

Saludos,

George

Re: Nueva clase TLayout

PostPosted: Tue Sep 24, 2013 7:58 pm
by rolando
Buenísimo Daniel, muchas gracias.

Saludos.

Rolando :D

Re: Nueva clase TLayout

PostPosted: Wed Oct 23, 2013 6:27 pm
by cnavarro
Daniel,
Se podria aplicar tu magnifica clase a este ejemplo?
viewtopic.php?f=3&t=27505#p153384

Re: Nueva clase TLayout

PostPosted: Fri Oct 25, 2013 3:41 am
by Daniel Garcia-Gil
Hola

si, de hecho iba a responder el post con un ejemplo usando layout, pero veo que funciona bien como lo presentaron, al parecer no es necesario

la clase TLayout es bastante buena tiene un potencial inmenso

aqui dejo un ejemplo, habria que copiarlo en la carpeta de samples de fivewin para que tome las ruta de las imagenes de forma correcta

Code: Select all  Expand view

#include "fivewin.ch"
#xcommand DEFINE LAYOUT <oLayout> <of:OF, WINDOW, DIALOG, LAYOUT> <oDlg> ;
    => ;
    <oLayout> := TLayout():new(<oDlg>)

#xcommand DEFINE VERTICAL LAYOUT [<oLayout>] OF <oMainLay> [ SIZE <nSize> ]  ;
    => ;
    [<oLayout> :=] <oMainLay>:addVLayout([<nSize>])

#xcommand DEFINE HORIZONTAL LAYOUT  [<oLayout>] OF <oMainLay> [ SIZE <nSize> ]  ;
    => ;
    [<oLayout> :=] <oMainLay>:addHLayout([<nSize>])

#xcommand SET LAYOUT CONTROL <oControl> OF <oLayout>;
    =>;
    <oLayout>:oClient := <oControl>


function main()

    local oWnd
    local xLay := {=>}
    local oBar1, oBar2


    define window oWnd

    define LAYOUT xLay["main"] of oWnd

    define VERTICAL LAYOUT of xLay["main"] size 32
    define VERTICAL LAYOUT of xLay["main"] size 32

    define buttonbar oBar1 of xLay["main"]:aVLayout[1] size 32,32 2010
    define buttonbar oBar2 of xLay["main"]:aVLayout[2] size 32,32 2007

    DEFINE BUTTON OF oBar1 FILENAME "..\bitmaps\alphabmp\bs_close.bmp"
    DEFINE BUTTON OF oBar2 FILENAME "..\bitmaps\alphabmp\bs_open.bmp"

    DEFINE BUTTON OF oBar1 FILENAME "..\bitmaps\alphabmp\bs_exit.bmp"
    DEFINE BUTTON OF oBar2 FILENAME "..\bitmaps\alphabmp\bs_options.bmp"

    activate window oWnd

return nil