Topic: AppGraphics Basics

Working on an AppGraphics DEMO example to include Lines, Bars, TextBoxes, Buttons,  Radio Buttons, and Check Boxes.   Would like to present the opening screen with a LIGHTGRAY Background.  Any  idea as to how to do this?

call setbkcolor(LIGHTGRAY) before initwindow() is not allowed.

Bob

Re: AppGraphics Basics

Bob,

I would suggest using the systemcolor() function combined with the constant COLOR_WINDOW_BKGD.   This combination would fill the background with a color that will match the current Windows theme (or it should, at least).

To cause the background color to fill the window upon creation, combine your code with a call to clearviewport, which doesn't appear to be in the online documentation.   The code would be:

call setbkcolor(systemcolor(COLOR_WINDOW_BKGD))
call clearviewport()
Jeff Armstrong
Approximatrix, LLC

Re: AppGraphics Basics

Bob,

There appears to be a few issues with checkboxes and radio buttons in the current build of AppGraphics.  A new build will be out tomorrow.  Sorry for any confusion.

Jeff Armstrong
Approximatrix, LLC

Re: AppGraphics Basics

I'd welcome seeing your demo example code, when it's ready, Bob.

Jeff, I think any example program showing how to build a GUI using AppGraphics, with menus, prompts, data entry fields, a little bit of vector graphics, and callback routines triggered as necessary (eg for data entry validation as well as to invoke the main program - rather like Clive Page did using Dislin - would really light up the Fortran world.

Bob, Jeff, and others, I believe from my own experience that people with many years of coding in Fortran for prompted text-screen and/or data file i/o, who are accustomed to linear program structure, can find CallBacks and the kind of loopy/recursive program structure a bit bewildering, and having an example is a huge help in making the transition form the 1970s to the 21st century!

If I only had time, I'd love to try to create an interesting example GUI, but I have too too much work on at the moment.
---
J.

Re: AppGraphics Basics

Bob, there's a new build of Simply Fortran available now that actually fixes some issues with checkboxes and radio buttons within AppGraphics.  The library was upgraded to version 1.4

John, I plan to get some more AppGraphics examples together.  I do realize it's difficult to just get up and running without some code to work with.  The "Conway's Game of Life" example that ships with Simply Fortran makes relatively heavy use of callbacks, though.  Have a look in the file "control.f90" to see how this little game handles buttons and menu clicks.

Jeff Armstrong
Approximatrix, LLC

Re: AppGraphics Basics

Tomorrow, I'll post a form for a demo project for comments.
Bob

Re: AppGraphics Basics

I've posted a sample application form which includes the controls previously discussed.  Comment freely if you want to suggest revisions to the form.


The form is at  http://n2006b.com/sfag/
Bob

Re: AppGraphics Basics

Bob,

So you've coded that window up in AppGraphics?  It looks quite good!  If you need any assistance or have any question, please don't hesitate to post here.

Jeff Armstrong
Approximatrix, LLC

Re: AppGraphics Basics

Actually the form was constructed in Visual Studio  for comment purposes only
The actual code contains a createbutton which fails.
Below is relevant code

integer :: start_button
start_button = createbutton(100, 200,120,50,"Button Test", btnTest())
!  The above is incorrect  but why 

Subroutine btnTest
! some code is here and works
End Subroutine btnTest

I can call btnTest from another place in the code successfully.

Any ideas ?

Bob

Re: AppGraphics Basics

You have declared btnTest to be a subroutine but in the call to createbutton you are using syntax which assumes it is a function.

Perhaps you should remove the parenthesis () from the btnTest argument.

If you are trying to pass a reference to the btnTest subroutine (so createbutton can call it) then you also need to declare it as EXTERNAL or provide an interface definition for it.

I have not looked at the syntax for createbutton so I cannot be sure this would solve all your problems.

--
David

Re: AppGraphics Basics

Bob,

You're close to correct on the createbutton call.  What you need to have is:

integer :: start_button
start_button = createbutton(100, 200,120,50,"Button Test", btnTest)

You are passing the subroutine itself, not a call to it.  If you include parentheses, you are implying that btnTest is either a function call or an array (if there had been anything in the parentheses).  The createbutton functions expects merely the name of an appropriate subroutine.

In the "Conway's Game of Life" example that ships with Simply Fortran, have a look at the file screen.f90 and, specifically, the init_screen subroutine where two buttons are created.  The subroutines they reference are, incidentally, located off in another module in the control.f90 file.

Jeff Armstrong
Approximatrix, LLC

Re: AppGraphics Basics

davidb wrote:

If you are trying to pass a reference to the btnTest subroutine (so createbutton can call it) then you also need to declare it as EXTERNAL or provide an interface definition for it.

David,

Using the EXTERNAL or providing an interface block is unnecessary as long as the subroutine being referenced in the createbutton call is within scope.

Jeff Armstrong
Approximatrix, LLC

13

Re: AppGraphics Basics

Below is the minimum code I would think ought to display a button and when clicked a message should be displayed.
Will it work for you ?
!================================================

program main       
use appgraphics
!   see  http://simplyfortran.com/docs/appgraphics/controls.html
implicit none
integer::myscreen
character * 30 :: msg
!----------------------------------------------------
msg = " Executing Test 94"                               
call dlgmessage(DIALOG_INFO,msg)
call InitializeScreen()
! call btnTest
call loop()
call closewindow(myscreen)
end program main  ! =========================== End main
                                     
!--------------------------------------------------------
Subroutine InitializeScreen()  ! ============ InitializeScreen()
use appgraphics
character * 30 :: msg2
integer :: start_button
msg2 = "In InitializeScreen()    "
myscreen = initwindow(400, 200, title="Controls Demo", closeflag=.TRUE.)
! call setbkcolor(systemcolor(COLOR_WINDOW_BKGD))
call setbkcolor(WHITE)
call clearviewport()  ! to display the windows background color
call dlgmessage(DIALOG_INFO,msg2)

call btnTest  ! and it executes as expected  but
! Comment out the above line and the build fails

start_button = createbutton(100, 200,120,50,"Button Test", btnTest)
call enablebutton(start_button, .TRUE.)

End Subroutine InitializeScreen
! ==================================================
Subroutine btnTest
    use appgraphics
    character * 30 :: msg4
    msg4 = "BtnTest was reached"
    call dlgmessage(DIALOG_INFO,msg4)
End Subroutine btnTest

! ---------------------------------------BR  Bob

Re: AppGraphics Basics

Bob,

Your program actually compiles and runs fine.  The only issue is your button placement.  Looking at your InitializeScreen routine:

Subroutine InitializeScreen()  ! ============ InitializeScreen()
use appgraphics
character * 30 :: msg2
integer :: start_button
msg2 = "In InitializeScreen()    "
myscreen = initwindow(400, 200, title="Controls Demo", closeflag=.TRUE.)
! call setbkcolor(systemcolor(COLOR_WINDOW_BKGD))
call setbkcolor(WHITE)
call clearviewport()  ! to display the windows background color
call dlgmessage(DIALOG_INFO,msg2)

call btnTest  ! and it executes as expected  but
! Comment out the above line and the build fails

start_button = createbutton(100, 200,120,50,"Button Test", btnTest)
call enablebutton(start_button, .TRUE.)

End Subroutine InitializeScreen

you'll note that the y-coordinate of your button is 200, but your window is also only 200 pixels tall.  If I move your button to a y-coordinate of 150:

start_button = createbutton(100, 150,120,50,"Button Test", btnTest)

it now appears in the window and behaves as one would expect.

Jeff Armstrong
Approximatrix, LLC

15

Re: AppGraphics Basics

Thanks and the button now works......however -
I still cannot run by clicking the green arrow.
When I click it, fwin fails and Taskmanager shows three instances of graphics.exe *32 are created.
On the other hand, if after a build  I dbl click the icon in Windows explorer, all works well.
If you can share any ideas, let me know.
BR
  Bob

16 (edited by jeff 2015-03-06 22:08:59)

Re: AppGraphics Basics

Bob,

Are you saying that Simply Fortran crashes when you click the green arrow on the toolbar?  That is a significant bug if so.  In what directory have you saved your Fortran source code, out of curiousity?

EDIT: I also wanted to ask:

1.  Does the Console tab open prior to crashing?
2.  Does your project have "Windows GUI" checked in the Project Options window?
3.  Do you currently have Build Before Launch enabled?
4.  Does every Simply Fortran project you have fail to launch when you click the toolbar button?

Sorry for all the trouble!

Jeff Armstrong
Approximatrix, LLC

17

Re: AppGraphics Basics

Answers: 1. No    2. Yes  3. No  I save build launch  manually 4. No

I think   fWin (not Responding) may have an issue with the long directory path like
J:\Fortran\Bobs Examples\Simply Fortran\AppGraphics01
When the project is placed on f:\  a jump drive ..it works as expected.
Since running from F:\  ( a jump drive ) works just fine,  I'm not that concerned.

Next issue .......  removing call btnTest line .

program main               !    Loading from F:\ a Jump Drive       
use appgraphics
!   see  http://simplyfortran.com/docs/appgraphics/controls.html
implicit none
integer::myscreen
character * 30 :: msg; msg = " Executing From F: Test 94"                               

call InitializeScreen()
call loop()
call closewindow(myscreen)
end program main  ! ===================== End main                                   
!--------------------------------------------------------
Subroutine InitializeScreen()  ! ============ InitializeScreen()
use appgraphics
character * 30 :: msg2
integer :: start_button
msg2 = "In InitializeScreen()    "
myscreen = initwindow(400, 200, title="Controls Demo", closeflag=.TRUE.)
!    call setbkcolor(systemcolor(COLOR_WINDOW_BKGD))
call setbkcolor(LIGHTGRAY)
call clearviewport()  ! to display the windows background color
call btnTest ! I should be able to remove this line  but when I
               ! Comment out the call btnTest line, the build fails since the
               ! start_button line gets a red underscore
start_button = createbutton(100, 100,120,50,"Button Test", btnTest)
call enablebutton(start_button, .TRUE.)
End Subroutine InitializeScreen
! ==================================================
Subroutine btnTest
    use appgraphics
    character * 30 :: msg4
    msg4 = "BtnTest was reached Attempt 4"
    call dlgmessage(DIALOG_INFO,msg4)
End Subroutine btnTest
-----------------------------------------------------------------------------

Any help is appreciated.
  Bob

Re: AppGraphics Basics

Bob,

You're having some minor scope issues associated with Fortran 90 and higher.  When you have the line call btnTest first, it is apparently alerting the compiler that btnTest is a subroutine.  When you use it only in the createbutton call, there is nothing to indicate it is a subroutine.  Because you haven't declared implicit none, the compiler (correctly) assumes that btnTest is a real (floating point) value.

If I add implicit none to the subroutine InitializeScreen, I actually end up with two errors because myscreen is also undeclared.  I would suggest, for this example, changing the code to:

program main               !    Loading from F:\ a Jump Drive       
use appgraphics
!   see  http://simplyfortran.com/docs/appgraphics/controls.html
implicit none

character * 30 :: msg; msg = " Executing From F: Test 94"                               

    call InitializeScreen()
    call loop()
    call closewindow()

contains

    !--------------------------------------------------------
    Subroutine InitializeScreen()  ! ============ InitializeScreen()
    use appgraphics
    implicit none
    
        character * 30 :: msg2
        integer :: start_button
        integer::myscreen
    
        msg2 = "In InitializeScreen()    "
        myscreen = initwindow(400, 200, title="Controls Demo", closeflag=.TRUE.)
        !    call setbkcolor(systemcolor(COLOR_WINDOW_BKGD))
        call setbkcolor(LIGHTGRAY)
        call clearviewport()  ! to display the windows background color

        start_button = createbutton(100, 100,120,50,"Button Test", btnTest)
        call enablebutton(start_button, .TRUE.)
    End Subroutine InitializeScreen
    
    ! ==================================================
    Subroutine btnTest
    use appgraphics
    implicit none

        character * 30 :: msg4
        msg4 = "BtnTest was reached Attempt 4"

        call dlgmessage(DIALOG_INFO,msg4)
    End Subroutine btnTest

end program main  ! ===================== End main 
Jeff Armstrong
Approximatrix, LLC

Re: AppGraphics Basics

Also, I'll look into why you're seeing a crash on program launch from the toolbar.  That's a pretty severe bug.

Jeff Armstrong
Approximatrix, LLC

20 (edited by davidb 2015-03-08 15:12:51)

Re: AppGraphics Basics

jeff wrote:

When you have the line call btnTest first, it is apparently alerting the compiler that btnTest is a subroutine.  When you use it only in the createbutton call, there is nothing to indicate it is a subroutine.  Because you haven't declared implicit none, the compiler (correctly) assumes that btnTest is a real (floating point) value.

This is normal for Fortran. It assumes that a sub-program argument is a function call unless you tell it otherwise (It has to do this because of the requirement to allow "independent compilation" in F77). As you note, in this case no error is reported because Implicit typing is being used. Potentially, an error could have been reported at link time but gfortran's linker is not that clever.

This is why I suggested using EXTERNAL or an interface block.

One rule that has always helped over the years is "be as explicit as possible to help the compiler".

For the crash when running from the toolbar, wasn't there a similar issue reported recently? I looked but could not find it.

--
David

Re: AppGraphics Basics

davidb wrote:

This is why I suggested using EXTERNAL or an interface block.

One rule that has always helped over the years is "be as explicit as possible to help the compiler".

For the crash when running from the toolbar, wasn't there a similar issue reported recently? I looked but could not find it.

David,

You're right.  In this particular case, since btnTest isn't explicitly known to the compiler from within the InitializeScreen subroutine, an interface or EXTERNAL declaration would be necessary.  I personally tend to use more Fortran-90-like scoping in all cases, throwing all subroutines and functions into modules to avoid issues like what Bob reported and avoid having to write interface blocks.

The crashing bug is a new one.  There was a similar issue recently where projects with spaces in their paths that aren't on the boot drive would not start.  However, that bug didn't cause a crash and has since been fixed.  I'm not sure exactly what Bob's seeing.

Jeff Armstrong
Approximatrix, LLC

22 (edited by davidb 2015-03-08 20:12:18)

Re: AppGraphics Basics

Indeed, using a module would be my preferred option too.

Bob wrote:

When I click it, fwin fails and Taskmanager shows three instances of graphics.exe *32 are created.

This just reminded me of the other issue Bob had in http://forums.approximatrix.com/viewtopic.php?id=434

--
David