FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin for Harbour/xHarbour NEW CLASS TLayout
Posts: 2365
Joined: Wed Nov 02, 2005 11:46 PM
NEW CLASS TLayout
Posted: Sun Sep 22, 2013 06:49 PM
Hello,

leave here a new class to build layout inside our windos, allow auto adjust control inside continer, we will can forget @ row, col and control size

to see effect, please resize window

it's a link with 2 samples (exe and sources included)

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

copy the samples inside fivewin samples folder

the source of 1 sample

Code (fw): Select all Collapse
#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 (fw): Select all Collapse
#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


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





Posts: 10733
Joined: Sun Nov 19, 2006 05:22 AM
Re: NEW CLASS TLayout
Posted: Sun Sep 22, 2013 09:07 PM

Very Nice and very useful!!!!
Uses are unlimited.

Regards



G. N. Rao.

Hyderabad, India
Posts: 1286
Joined: Mon Feb 25, 2008 02:54 PM
Re: NEW CLASS TLayout
Posted: Mon Sep 23, 2013 01:22 AM

Thanks :)

ubiratanmga@gmail.com

FWH24.04
BCC7.3
HARBOUR3.2
xMate
Pelles´C
TDolphin
Posts: 7317
Joined: Thu Oct 18, 2012 07:17 PM
Re: NEW CLASS TLayout
Posted: Mon Sep 23, 2013 07:46 AM

Nice Daniel,
Instead of buttons we can use explorerbar ?
it's possible insert a splitter from a xbrowse to another ? (sample : layout.prg - > from xbrowse and folderex)

Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)

I use : FiveWin for Harbour March-April 2024 - Harbour 3.2.0dev (harbour_bcc770_32_20240309) - Bcc7.70 - xMate ver. 1.15.3 - PellesC - mail: silvio[dot]falconi[at]gmail[dot]com
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: NEW CLASS TLayout
Posted: Mon Sep 23, 2013 02:15 PM

Daniel,

You keep being the magician of the numbers (amongst many other areas) :-)

many thanks

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 195
Joined: Sun Jul 22, 2012 07:01 PM
Re: NEW CLASS TLayout
Posted: Mon Sep 23, 2013 04:30 PM
When I compile this I get a persistent unresolved external error for _Max, using VS2012 32 bit and harbour. Adding a dummy function _Max() does not clear the error and at least allow it to link, and adding a function Max() throws a conflict error with a harbour. Any idea how to resolve this?

Compiling...
Harbour 3.2.0dev (r1309161336)
Copyright (c) 1999-2013, http://harbour-project.org/
Compiling 'test_layout.prg' and generating preprocessed output to 'test_layout.p
po'...
Lines 4782, Functions/Procedures 8
Generating C source output to 'test_layout.c'... Done.
Microsoft (R) C/C++ Optimizing Compiler Version 17.00.60610.1 for x86
Copyright (C) Microsoft Corporation. All rights reserved.

test_layout.c
Creating library test_layout.lib and object test_layout.exp
FiveH32.lib(FLDEX.obj) : error LNK2019: unresolved external symbol _Max referenc
ed in function _CalcPos

test_layout.exe : fatal error LNK1120: 1 unresolved externals
* Linking errors *
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: NEW CLASS TLayout
Posted: Mon Sep 23, 2013 04:39 PM

Robb,

There is a 2nd revision of FWH 13.08 that solves that issue, are you using it ? In FWH web site it is shown and also when you run the FWH setup (fwh.exe)

We have announced it in the forums, but maybe you missed it, thanks

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: NEW CLASS TLayout
Posted: Mon Sep 23, 2013 04:55 PM

Robb,

Due two little bugs found today, we are going to publish a third revision of FWH 13.08 and we expect to publish it today.

We have been talking (Rao, Daniel, me) about a way to reduce these bugs on new versions, and my opinion is that we need a very complete FWH test app that tests almost every FWH feature, but how to build it ?

Usually we build and test large apps that we have built but they don't test all possibilities in FWH and this is the problem. Even if we stop changing code for some days, if we don't tests all the possibilities, then the bugs will remain there and will reach the users. So for now, the only valid way to asure a bug free version is after some of you build your apps and check that they are fine. Fortunately just a few of us are needed to quickly check this.

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 3022
Joined: Fri Oct 07, 2005 01:45 PM
Re: NEW CLASS TLayout
Posted: Mon Sep 23, 2013 05:05 PM

Antonio,

Bugs are just part of the process. Sometimes a release needs to go general and be tested across a wide range of systems for all the bugs to be found. Technology is so complex today, I'm not sure any test program can actually evaluate every possible opportunity for bugs.

Tim

Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: NEW CLASS TLayout
Posted: Mon Sep 23, 2013 05:18 PM

Tim,

I fully agree with you. If we adopt a conservative way to get a bug free version, then we will be blocking us for all the new features and enhancements that we are constantly adding to FWH. Anyhow, usually in less than a week we have a real stable version, so it is not so long time to be patient :-)

thanks for the understanding :-)

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 3022
Joined: Fri Oct 07, 2005 01:45 PM
Re: NEW CLASS TLayout
Posted: Mon Sep 23, 2013 07:07 PM

Antonio,

Its because of the integration between various functions/methods. Sometimes what we do in one area of a program may be used somewhere else and have a different effect. In theory, classes should be self contained, but sometimes changing a class will have a result in how it is implemented elsewhere, like in a sub class. We only find this out when we apply the newly changed class and see a result pop up.

You can't test for this ! We just have to fix it when it occurs.

Tim

Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: NEW CLASS TLayout
Posted: Mon Sep 23, 2013 07:20 PM

In this case it was a C function that was similar in C5 and in FWH, so we combined both but there was a little mistake, and because that function was used from different places, the bug spreaded easily.

The lesson is that just a little change in a little C function is enough to break an app... We knew this, but it is quite difficult to protect from it. When it happens, it happens.

Anyhow, we are a great team (ALL OF US), and we have an incredibly reaction speed so a bug remains alive very little time between us :-)

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 195
Joined: Sun Jul 22, 2012 07:01 PM
Re: NEW CLASS TLayout
Posted: Tue Sep 24, 2013 12:44 AM

Thank you, that addressed the problem and I am able to build the test programs now.

Daniel, I did not mean to be so rude and appear so thankless. This is a wonderful class, practical, useful and educational. Thank you so much for sharing.

Antonio, I understand the testing challenges. Personally I choose to write unit test code for every new class and function I write, not too different than the test utility that is provide with harbour itself. It doesn't catch everything, but it catches a lot. Nothing new ever makes it to my main build machine before it passes on my sandbox machine where I run all the tests. This code was being tested on the sandbox. My test utilities wouldn't have caught this one. As always, thank you for the prompt attention.

Robb

Posts: 1303
Joined: Tue Jul 21, 2009 08:12 AM
Re: NEW CLASS TLayout
Posted: Tue Sep 24, 2013 08:39 AM

Antonio,

You may consider to have a Certification section at Fivetech, where the incomming libs should be tested with a real application before launching the new build to the public.

Also, to create a big application to use as many as controls posible: all classic gets, says, folders, etc, plus ribbon, richedit, xbrowse, report, etc etc.

In this application calls to setresdebug() and checkres should be incorporated to detect remaining objets. I beleive there are one at rpreview.prg, the richedit was fixed?

FiveDbu uses very Little of those controls, so it is not good to test the libs.

But also it is very important to say that bugs are very quicly solved here.

Thank you.

Muchas gracias. Many thanks.



Un saludo, Best regards,



Harbour 3.2.0dev, Borland C++ 5.82 y FWH 13.06 [producción]



Implementando MSVC 2010, FWH64 y ADO.



Abandonando uso xHarbour y SQLRDD.
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: NEW CLASS TLayout
Posted: Tue Sep 24, 2013 10:53 AM

Lucas,

We are not Microsoft, neither the company where you work at.

Not all the companies are the big and have the resources as the one where you work at :-)

We do our best to provide the tools that we use for building our own apps. If you are not satisfied with us, please consider to use Microsoft tools, etc. there are lots of choices availables.

We pay good care of reasonable suggestions. But they have to be reasonable :-)

regards, saludos

Antonio Linares
www.fivetechsoft.com