LB Booster
« Liberty Composer »

Welcome Guest. Please Login or Register.
Apr 1st, 2018, 03:52am



ATTENTION MEMBERS: Conforums will be closing it doors and discontinuing its service on April 15, 2018.
We apologize Conforums does not have any export functions to migrate data.
Ad-Free has been deactivated. Outstanding Ad-Free credits will be reimbursed to respective payment methods.

Thank you Conforums members.
Speed up Liberty BASIC programs by up to ten times!
Compile Liberty BASIC programs to compact, standalone executables!
Overcome many of Liberty BASIC's bugs and limitations!
LB Booster Resources
LB Booster documentation
LB Booster Home Page
LB Booster technical Wiki
Just BASIC forum
BBC BASIC Home Page
Liberty BASIC forum (the original)

« Previous Topic | Next Topic »
Pages: 1  Notify Send Topic Print
 thread  Author  Topic: Liberty Composer  (Read 626 times)
Jack Kelly
Full Member
ImageImageImage


member is offline

Avatar




Homepage PM

Gender: Male
Posts: 106
xx Liberty Composer
« Thread started on: Jun 18th, 2016, 6:48pm »

Cundo has been working on a graphic window generator program which he has posted on the LB forum. I would like to run it on LBB but the generated code does not get the position and size of the controls. He says it works correctly on LB45. I have worked for several hours unsucessfully trying to figure out why. Three clicks shows the problem -- Menu, add button, Produce Code. The code is printed to MainWin.

Code:
'Drag the controls, clicking on them. Resize them clicking the little square 
'at the bottom of each control. Right click deletes the control below the 
'cursor.
app$= "Liberty Composer v111"
'   (Previously named: Super simple visual designer)
'   (c) 2016 by cundo
'   Find discussion and updates if any at : libertybasic.conforums.com
    global control, grid, avoidList$
    dim controlType$(100)
    grid=24
    WindowWidth = 640 : WindowHeight = 480
    UpperLeftX = INT((DisplayWidth-WindowWidth)/2)
    UpperLeftY = INT((DisplayHeight-WindowHeight)/2)
    width=WindowWidth-150 : height=WindowHeight-150
    stylebits   #main.gbx,_WS_SIZEBOX OR _WS_BORDER or _WS_CAPTION, 0, 0, 0
    graphicbox  #main.gbx, WindowWidth/2-width/2, WindowHeight/2-height/2, width, height
    stylebits   #main.add, 0, 0, 0, 0
    button      #main.add,"&Menu",[addControl],ul,1,1,50,28
    button      #main.en,"&Enable all",[enableControls],ul,100,1,75,28
    button      #main.code,"&Produce Code",  [code],ul,176,1,150,28
    Open app$ For window As #main
    call DrawGrid "#main.gbx",width*2,height*2
    #main "trapclose quit"
    wait

  [code]
cls

    Call GetRect hWnd(#main.gbx),winx,winy,winwidth,winheight
    Print "NoMainWin"

    Print "WindowWidth = ";winwidth ;" : WindowHeight = " ;winheight
    Print "UpperLeftX = INT((DisplayWidth-WindowWidth)/2)"
    Print "UpperLeftY = INT((DisplayHeight-WindowHeight)/2)"
    Print

 for i = 1 to control
   if instr(avoidList$,";#";i)=0 then
    h$= "#";i;".b1"
    call GetRect hWnd(#h$),nul  , nul , codewidth ,codeheight
    h =  hWnd(#main.gbx)
    Calldll #user32, "ScreenToClient",h As ulong,Rect As struct,result as void
    codex=Rect.x1.struct
    codey=Rect.y1.struct

    print controlType$(i);",";str$(codex);",";str$(codey);_
    ",";str$(codewidth);",";str$(codeheight)
'    print controlType$(i);",";str$(px);",";str$(py);_
'    ",";str$(controlWidth);",";str$(controlHeight)
  end if
 next i

    Print
    Print "Open ";chr$(34);"Window";chr$(34);" for Window as #main"
    Print "#main ";chr$(34);"trapclose [quit]";chr$(34)
    Print "wait"
    Print
    Print "[quit]"
    Print "close #main"
    Print "End"

wait

[enableControls]
if control then
    #main.en word$("&Disable all; &Enable all",areOn+1,";")
    areOn = abs(not(areOn))
    for i = 1 to control
        EnableThisHandle$ = "#";i;".b1"
        EnableThisWHandle$= "#";i
        call EnableWindow hWnd(#EnableThisHandle$), areOn
    next
end if

wait

[addControl]
    color$="BUTTONFACE"
    controlWidth=100 : controlHeight=30
    px= int(rnd(0)*(400-controlWidth))
    py= int(rnd(0)*(300-controlHeight-30))
    WindowWidth =controlWidth : WindowHeight = controlHeight
    dim array$(10)
    for i = 1 to 10
     array$(i)="Drag me please"
    next
    stylebits #101.gfx, 0, _WS_BORDER, 0, 0
    stylebits #101.b1, _WS_DISABLED, 0, 0, 0
    gfxw=controlWidth : gfxh=controlHeight
    graphicBox  #101.gfx, px,py,gfxw+9,gfxh+9
    popupmenu "add button",[buttonCode],"add textbox",[txtCode],_
        "add listbox",[listCode],"add static",[staticCode],_
         "add combobox",[comboCode],"add radiobutton",[radioCode],_
          "add texteditor",[edCode],"add checkbox",[chkCode],_
           "add graphicbox",[blank]
    wait

[buttonCode]
    type$="button #main.b";control+1;",";chr$(34);"Button";chr$(34);_
    ", [quit],ul"
    button  #101.b1,"Drag me ";control+1,dummy,ul,_
    0,0,controlWidth,controlHeight :goto [createWindow]
[txtCode]
    type$="textbox #main.tb";control+1
    textbox #101.b1,0,0,controlWidth,controlHeight : goto [createWindow]
[listCode]
    type$="listbox #main.lbx";control+1;",ar$(,dummy"
    listbox #101.b1, array$(), dummy,_
     0, 0, controlWidth, controlHeight : goto [createWindow]
[staticCode]
    type$="statictext #main.st";control+1;",";chr$(34);"static";chr$(34)
    statictext #101.b1,"Drag me",_
    0,0,controlWidth,controlHeight  : goto [createWindow]
[comboCode]
    type$="combobox #main.combo";control+1;",ar$(,dummy"
    combobox #101.b1, array$(), dummy,_
     0, 0, controlWidth, controlHeight  : goto [createWindow]
[radioCode]
    type$="radiobutton #main.rb";control+1;",";chr$(34);"Radio";chr$(34);_
    ",dummy,dummy"
    radiobutton #101.b1, "Drag me", dummy, dummy,_
     0, 0, controlWidth, controlHeight  : goto [createWindow]
[edCode]
    type$="texteditor #main.txt";control+1
    texteditor #101.b1, 0, 0,_
     controlWidth, controlHeight  : goto [createWindow]
[chkCode]
    type$="checkbox #main.rb";control+1;",";chr$(34);"Radio";chr$(34);_
          ",dummy,dummy"
    checkbox #101.b1, "Drag me", dummy, dummy,_
     0, 0, controlWidth, controlHeight : goto [createWindow]
[blank]
    type$="graphicbox #main.gbx";control+1
    stylebits #101.b1, _WS_BORDER OR _WS_DISABLED, 0, 0, 0
    ' dummy control, I just need a 'b1' control
    statictext #101.b1,"",0,0,controlWidth,controlHeight
   ' stylebits #101.gfx, 0,0,0,0 : color$="WHITE;|";chr$(13);"hello"

[createWindow]
    ' needs a menu supported window to avoid an error.log entry
    ' 'Kill BASIC Apps'
    stylebits #101, _WS_SYSMENU, _WS_VISIBLE,0, 0
    Open "" For window_popup As #101
    #101.gfx "down;fill ";color$
    #101.gfx "place ";gfxw;" ";gfxh
    call Draw "#101.gfx", gfxw, gfxh
    #101.gfx "When leftButtonMove lbm"
    #101.gfx "When rightButtonDown delete"
    call setParent hWnd(#101.gfx),hWnd(#101.b1)
    call setParent hWnd(#main.gbx),hWnd(#101.gfx)
    control=control+1
    controlType$(control)=type$
    newHandle$="#";control
    maphandle #101,newHandle$
Wait

Sub quit h$
    for i  = 1 to control
       newHandle$="#";i
       if instr(avoidList$,newHandle$)=0 then
        close #newHandle$ 
       end if
    next
   close #main
 End
End Sub

Sub lbm h$, X, Y
handler$ = Word$(h$, 1, ".")
hWnd = hWnd(#h$)
'print h$,handler$

    CallDll #user32, "ReleaseCapture",r As void
    Call GetRect hWnd, nul  , nul , w ,h

    q=_HTCAPTION  'by default, grab the window
    if abs(w-X)<=10 AND abs(h-Y)<=10 then
            ' the lower right corner
            ' means a resize event
            q=_HTBOTTOMRIGHT
    end if

 CallDLL #user32, "SendMessageA", _
    hWnd As ULong, _
    _WM_NCLBUTTONDOWN As ULong, _
    q As uLong, _
    0 As Long, _
    r As void

    'also resize the control inside the graphicbox
    if q=_HTBOTTOMRIGHT then
        Call GetRect hWnd, nul  , nul , w ,h
        w=w-9 : h = h-9
        b1h$ = handler$;".b1"
        b1h = hwnd(#b1h$)
        call MoveWindow b1h,0,0,w,h
        call Draw h$,w,h
    end if

        ' align to grid
        Call GetRect hWnd, nul  , nul , w ,h
        main = hWnd(#main.gbx)
        Calldll #user32, "ScreenToClient",main As ulong,Rect As struct,result as void
        x1 = int(Rect.x1.struct/grid)*grid
        y1 = int(Rect.y1.struct/grid)*grid
        Call MoveWindow hWnd,x1,y1, w, h

End Sub

Sub delete h$,x,y
    win$ = word$(h$,1,".")
    n$=word$(h$,2,".")
    confirm "Delete this control?"; responseVar$
     If responseVar$="yes" Then
        close #win$ 
        avoidList$=avoidList$;";";win$
     End if
End Sub
Sub dummy h$
End Sub
Sub setParent parent,child
    calldll #user32, "SetParent",_
        child as ulong,_
        parent as ulong,_
        r as void
End Sub
Sub ShowWindow hWnd, flag
    CallDLL #user32, "ShowWindow",_
    hWnd as uLong, flag As uLong,_
    r As void
End Sub
Sub EnableWindow hWnd, flag
    CallDLL #user32, "EnableWindow",_
     hWnd as uLong, flag As uLong,_
     r As void
End Sub
Sub GetWindowRect hW
    struct Rect, x1 As Long, y1 As Long, x2 As Long, y2 As Long
    CallDLL #user32, "GetWindowRect",_
    hW as uLong,Rect As struct, result As void
End Sub
Sub Draw h$,x,y
        #h$ "cls;fill buttonface;";_
            "place ";x-1;" ";y-1
        #h$ "color buttonface"
        #h$ "backcolor buttonface"
        #h$ "rule ";_R2_NOT
        #h$ "boxfilled ";x+5;" ";y+5
        #h$ "line ";x;" ";y+2;" ";x+5;" ";y+2
        #h$ "line ";x+2;" ";y;" ";x+2;" ";y+5
        #h$ "flush"
End sub
Sub DrawGrid h$,width,height
        #h$ "cls"
        #h$ "down;fill buttonface ;flush"
        #h$ "size 1;color BLACK"
        for x = 0 to width step grid
         for y = 0 to height step grid
             #h$ "set ";x;" ";y
        next:next
        #h$ "flush;up"
        #h$ "setfocus"
End Sub
Sub MoveWindow hnd,x,y,w,h
        calldll #user32, "MoveWindow",_
        hnd as ulong, _       'window handle
        x as long,_            'x location of gfx window
        y as long,_            'y location of gfx window
        w as long,_           'desired width of window
        h as long,_           'desired height of window
        1 as long,_             'repaint flag,0=false,1=true
        ret as void             'nonzero=success
End Sub

Sub GetRect hnd, byref x  , byref y , byref w ,byref h
    call GetWindowRect hnd
    x= Rect.x1.struct
    y= Rect.y1.struct
    w= Rect.x2.struct-Rect.x1.struct
    h= Rect.y2.struct-Rect.y1.struct
End SUb
'include lb45func.bas
 
User IP Logged

Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 1348
xx Re: Liberty Composer
« Reply #1 on: Jun 18th, 2016, 8:13pm »

on Jun 18th, 2016, 6:48pm, Jack Kelly wrote:
I have worked for several hours unsucessfully trying to figure out why.

It's a documented incompatibility. In fact it's item 4 in the Compatibility section of the LBB docs:

"Child control handles must be mapped explicitly, e.g. MAPHANDLE #old.te,#new.te; mapping the parent window's handle is not sufficient".

So to make the program work correctly in LBB you need to replace this line (154):

Code:
    maphandle #101,newHandle$ 

with this Code:
    maphandle #101.b1,newHandle$;".b1"
    maphandle #101.gfx,newHandle$;".gfx"
    maphandle #101,newHandle$ 

This modification is compatible with LB, so may safely be left in the program.

Richard.
User IP Logged

Jack Kelly
Full Member
ImageImageImage


member is offline

Avatar




Homepage PM

Gender: Male
Posts: 106
xx Re: Liberty Composer
« Reply #2 on: Jun 18th, 2016, 10:12pm »

Thank you, Richard, for coming to my rescue AGAIN. I am grateful for your help!
User IP Logged

Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 1348
xx Re: Liberty Composer
« Reply #3 on: Jun 21st, 2016, 9:20pm »

on Jun 18th, 2016, 6:48pm, Jack Kelly wrote:
Cundo has been working on a graphic window generator program which he has posted on the LB forum.

There's a comment over at the LB Community Forum as follows: "When you right click a control, what it does is to close the hidden window which is holding it.... then the control disappears".

This analysis seems to be based on the assumption that the "control" is a child of the "hidden window" - but it isn't! When originally created that is the case, but the program uses the SetParent API to change the control's parent from the hidden window to the main graphicbox!

So when you right-click and request that the control be deleted, the hidden window is closed as expected, but the control does not disappear because it is no longer a child of that hidden window.

The solution is to restore the original parent-child relationship before the parent window is closed, then the control does indeed disappear:

Code:
Sub delete h$,x,y
    win$ = word$(h$,1,".")
    n$=word$(h$,2,".")
    confirm "Delete this control?"; responseVar$
     If responseVar$="yes" Then
        hp = hwnd(#win$)
        hc = hwnd(#h$)
        call setParent hp, hc ' restore parent-child relationship
        close #win$
        avoidList$=avoidList$;";";win$
     End if
End Sub 

The interesting thing is that, apparently, in LB 4.5.0 the control does disappear, despite not being a child of the window that is closed. Why?

Richard.
« Last Edit: Jun 21st, 2016, 9:29pm by Richard Russell » User IP Logged

Jack Kelly
Full Member
ImageImageImage


member is offline

Avatar




Homepage PM

Gender: Male
Posts: 106
xx Re: Liberty Composer
« Reply #4 on: Jun 22nd, 2016, 11:26am »

Thanks for following up with this, Richard. I'm really having a lot of fun enhancing this program. As I've said previously, I am better at orchestration than composition. I hope to use the program extensively in my future development projects. I'd really like to post my version, but I don't think cundo would appreciate that.
User IP Logged

Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 1348
xx Re: Liberty Composer
« Reply #5 on: Jun 22nd, 2016, 11:59am »

on Jun 22nd, 2016, 11:26am, Jack Kelly wrote:
I'd really like to post my version, but I don't think cundo would appreciate that.

Really? Is he claiming Copyright infringement or something? Usually when people post code to forums they encourage others to improve on it!

What aspects of cundo's program do you feel make it better than FreeForm? That's Open Source so I think anybody can publish modified versions so long as the Copyright notice is retained.

Richard.
User IP Logged

Jack Kelly
Full Member
ImageImageImage


member is offline

Avatar




Homepage PM

Gender: Male
Posts: 106
xx Re: Liberty Composer
« Reply #6 on: Jun 22nd, 2016, 1:05pm »

I've never been able to get FreeForm to run. I always seem to be missing some file that I can't manage to find. Once when I did get it to run under JB, it seemed a bit creaky and quirky.

I can't run LB anymore on my system. The trial period has expired and I have no intention of paying for it.
User IP Logged

Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 1348
xx Re: Liberty Composer
« Reply #7 on: Jun 22nd, 2016, 2:25pm »

on Jun 22nd, 2016, 1:05pm, Jack Kelly wrote:
I've never been able to get FreeForm to run. I always seem to be missing some file that I can't manage to find.

FreeForm uses several bitmap files in LB's bmp folder so it is necessary to have LB installed (it doesn't matter if the trial period has expired). So download FreeForm_LBB.bas to the folder where LB's example programs are - that will probably be %appdata%\Liberty BASIC v4.04\ or %appdata%\Liberty BASIC v4.5.0\ depending on what version it is, and run it using LBB.

That should give you a working version of FreeForm that does not depend on LB, except for the bitmap files. You could always replace those with your own custom versions if you want to be entirely independent of LB. FreeForm states specifically that it is Open Source so there shouldn't be any IPR issues so long as you retain the Copyright notice.

Quote:
Once when I did get it to run under JB, it seemed a bit creaky and quirky.

The JB version of FreeForm is significantly different from the LB version.

Richard.
User IP Logged

Jack Kelly
Full Member
ImageImageImage


member is offline

Avatar




Homepage PM

Gender: Male
Posts: 106
xx Re: Liberty Composer
« Reply #8 on: Jun 23rd, 2016, 11:19am »

I got Freeform up and running thanks to your excellent directions, Richard. My initial impression is that it's everything for everybody but perhaps a bit too much for me personally. Cundo's Liberty Composer is now tailored to the way I like to work, and the code is almost understandable. However, I will continue to evaluate Freeform and perhaps take some of its features over to LC, if possible. Thanks again for all your support. It's truly a privilege to be able to work with you.
User IP Logged

Pages: 1  Notify Send Topic Print
« Previous Topic | Next Topic »

| |

This forum powered for FREE by Conforums ©
Terms of Service | Privacy Policy | Conforums Support | Parental Controls