• Welcome to PlanetSquires Forums.
 

Firefly, Freebasic, FLTK question

Started by QuasiModule, April 20, 2016, 09:40:20 PM

Previous topic - Next topic

QuasiModule

Hello all. As you can guess I am new to this combination and have hit a very basic snag.
I am just trying to implement some FLTK widgets into a FF FB project. I can understand that getting non native widgets to appear in the visual designer would be close to impossible but I cannot get them to even appear in the final exe.
This is just a straight forward FLTK project and works fine. Compiles, runs, the works. Doesnt do much but is a POC

#Include "fltk-c.bi"
#Include "string.bi"

Type flStruct
    flClass as String       '
    flRight as Integer      ' Widget X
    flTop as Integer        ' Widget Y
    flWidth as Integer      ' Widget Width
    flHeight as Integer     ' Widget Height
    flLabel as String       ' Widget Label
End Type

Dim Shared flDial1 as flStruct
flDial1.flClass = "Fl_Dial"
flDial1.flRight = 10
flDial1.flTop = 160
flDial1.flWidth = 20
flDial1.flHeight = 20
flDial1.flLabel = "1"


'Windows and widgets:
Dim Shared as Fl_Window Ptr Window_Main
Dim Shared as Fl_Menu_Bar Ptr Menu
Dim Shared as Fl_Box Ptr Box_text
Dim Shared as Fl_Output Ptr Output_text
Dim Shared as Fl_Dial Ptr Dial1
Dim Shared as Fl_Dial Ptr Dial2
Dim Shared as Fl_Dial Ptr Dial3
Dim Shared as Fl_Button Ptr Button1_Click
Dim Shared as Fl_Button Ptr Button2_Click

Sub Create_Window_Main ()
'Window with button and Stuff:

    Window_Main = Fl_WindowNew (400, 200, "Button Test")

    Menu = Fl_Menu_BarNew (0, 0, 400, 20)
    Fl_Menu_Add (Menu, "File/New" ,,@flNewFile())
    Fl_Menu_Add (Menu, "File/Open" ,, @flOpenFile())
    Fl_Menu_Add (Menu, "File/Save" ,, @flSaveFile())
    Fl_Menu_Add (Menu, "File/Exit" ,, @flEndProgram())
    Fl_Menu_Add (Menu, "Edit" ,, @flDefault())
    Fl_Menu_Add (Menu, "Search" ,, @flDefault())
    Fl_Menu_Add (Menu, "View" ,, @flDefault())
    Fl_Menu_Add (Menu, "Tools" ,, @flDefault())
    Fl_Menu_Add (Menu, "Help/Info" ,, @flInfo())

    Box_text = Fl_BoxNew(150, 50, 100, 20, "Welcome to FLTK! with FreeBasic")
    Output_text = Fl_OutputNew (20, 140, 60, 20, "")
    Dial1 = Fl_DialNew (flDial1.flRight, flDial1.flTop, flDial1.flWidth, flDial1.flHeight, flDial1.flLabel)
    Dial2 = Fl_DialNew (flDial1.flRight+30, flDial1.flTop, flDial1.flWidth, flDial1.flHeight, "2")
    Dial3 = Fl_DialNew (flDial1.flRight+60, flDial1.flTop, flDial1.flWidth, flDial1.flHeight, "3")
    Fl_DialAngles(Dial1, 10, 350)
    Fl_DialAngles(Dial2, 10, 350)
    Fl_DialAngles(Dial3, 10, 350)
    Button1_Click = Fl_ButtonNew (160, 160, 100, 20, "Click me!")
    Button2_Click = Fl_ButtonNew (280, 160, 100, 20, "Not me!")
End Sub


'Menu Callback functions:

Sub flNewFile CDecl (widget as Fl_Widget Ptr, userData as Any Ptr)
    flMessageBox ("File Menu", "New file")
End Sub

Sub flOpenFile CDecl (widget as Fl_Widget Ptr, userData as Any Ptr)
    'Select a file to open:
    Dim as ZString Ptr file
    file = flFileChooser ("Open file", "*.bas" + Chr(9) + "*.txt", Exepath(), 1)
    If file <> 0 Then flMessageBox ("Selected file:", file)
End Sub

Sub flSaveFile CDecl (widget as Fl_Widget Ptr, userData as Any Ptr)
    ' Just some silly crap for testing
    Dim s as String
    s = *flInput ("Enter your name:", "Who are you?")
    If s <> "" Then flMessageBox ("Save file", "Hello " + s)
End Sub

Sub flEndProgram CDecl (widget as Fl_Widget Ptr, userData as Any Ptr)
    End
End Sub

Sub flInfo CDecl (widget as Fl_Widget Ptr, userData as Any Ptr)
    'Show Info:
    flMessageBox ("Help Menu", "Application Info")
End Sub

Sub flDefault CDecl (widget as Fl_Widget Ptr, userData as Any Ptr)
    'Show Info:
    flMessageBox ("Other Menu's", "Not yet implemented")
End Sub


'Callback functions for the Buttons and Dials
Sub Button1_Click_Event CDecl (widget as FL_Widget Ptr)

  Print "Button1 was clicked!"
    'Show Info:
    Fl_ValuatorSetValue(Dial1, 0.5)
    Fl_ValuatorSetValue(Dial2, 0.5)
    Fl_ValuatorSetValue(Dial3, 0.5)
    Dial1_Event(Dial1, widget)
    'flMessageBox ("You clicked Button 1", "Menu test program")
    ' End
End Sub

Sub Button2_Click_Event CDecl (widget as FL_Widget Ptr)

  Print "Button2 was clicked!"
    'Show Info:
    flMessageBox ("You clicked Button 2", "I said NOT ME!")
    End
End Sub

Sub Dial1_Event CDecl (widget as Fl_Widget Ptr, userData as Any Ptr)
    Dim X_ as Double
    Dim text as String
    'X_ = (Fl_ValuatorGetValue(Dial1) * 340) + 10
    X_ = Fl_ValuatorGetValue(Dial3)
    X_ += Fl_ValuatorGetValue(Dial2) * 59
    X_ += Fl_ValuatorGetValue(Dial1) * 300
    'X_ *= 3.243243243
    text = Format(X_, "###.##°")
    Fl_Input_SetValue (Output_text, text)
    ' or the GN4RLY Hardcore c style below. Which works by the way
    Select  Case widget
        Case Dial1
            'If widget = Dial1 Then
                'Fl_Input_SetValue (Output_text, Format(((Fl_ValuatorGetValue(Dial1) * 340) + 10), "###.##°"))
            'EndIf
        Case Dial2
            'If widget = Dial2 Then
                'Fl_Input_SetValue (Output_text, Format(((Fl_ValuatorGetValue(Dial2) * 340) + 10), "###.##°"))
            'EndIf
        Case Dial3
            'If widget = Dial3 Then
                'Fl_Input_SetValue (Output_text, Format(((Fl_ValuatorGetValue(Dial3) * 340) + 10), "###.##°"))
            'EndIf
        Case Else
            ' Fucked up?
    End Select
End Sub

'Main program:
Create_Window_Main ()
Fl_WidgetSetCallback0(Button1_Click, @Button1_Click_Event())
Fl_WidgetSetCallback0(Button2_Click, @Button2_Click_Event())
Fl_WidgetSetCallback0(Dial1, @Dial1_Event())
Fl_WidgetSetCallback0(Dial2, @Dial1_Event())
Fl_WidgetSetCallback0(Dial3, @Dial1_Event())
Fl_WindowShow(Window_Main)
Fl_Run

End


This on the other hand compiles with no errors but does not have the FLTK button.

#Include Once "fltk-c-1.3.3/fltk-c.bi"

Dim Shared as Fl_Button Ptr FLButton1

'--------------------------------------------------------------------------------
Sub FLButton1_Event CDecl (widget as FL_Widget Ptr)
    MessageBox( HWND_FBFORM, "Not here", "FLButton1 Event", MB_OK Or MB_DEFBUTTON1 Or MB_APPLMODAL )
End Sub

'--------------------------------------------------------------------------------
Function FBFORM_COMMAND1_BN_CLICKED ( _
                                    ControlIndex     as Long, _      ' index in Control Array
                                    hWndForm         as HWnd, _      ' handle of Form
                                    hWndControl      as HWnd, _      ' handle of Control
                                    idButtonControl  as Long   _     ' identifier of button
                                    ) as Long
   Select Case MessageBox( hWndForm, "Exit Button Properties" + Chr(13,10) + _
                        "Top = 230" + Chr(13,10) + _
                        "Left = 400" + Chr(13,10) + _
                        "Width = 70" + Chr(13,10) + _
                        "Height = 30", "FB-FLTK", _
                        MB_OK Or MB_DEFBUTTON1 Or MB_APPLMODAL )
        Case IDOK
            End
        Case Else
            MessageBox( hWndForm, "WTF?", "FB-FLTK Error" + Chr(13,10) + "Unknown button pressed", _
                        MB_OK Or MB_DEFBUTTON1 Or MB_APPLMODAL )
   End Select
   Function = 0   ' change according to your needs
End Function


'--------------------------------------------------------------------------------
Function FBFORM_WM_CREATE ( _
                          hWndForm as HWnd, _          ' handle of Form
                          ByVal UserData as Integer _  ' optional user defined value
                          ) as Long
    FLButton1 = Fl_ButtonNew (230, 300, 70, 30, "FLTK Button")  ' Should be in front of Exit Button
    Fl_WidgetSetCallback0(FLButton1, @FLButton1_Event())

   Function = 0   ' change according to your needs
End Function


I can find the FF declarations of the command1 button but they are in the codegen files and of course get overwritten at compile time so no point in editing there and as far as I can figure Create should create. Here is the compilation log that does not help much.

FreeBASIC Compiler - Version 1.05.0 (01-31-2016), built for win32 (32bit)
Copyright (C) 2004-2016 The FreeBASIC development team.
standalone
target:       win32, 486, 32bit
compiling:    CODEGEN_FBFLTK_MAIN.bas -o CODEGEN_FBFLTK_MAIN.asm (main module)
assembling:   f:\FreeBasic\bin\win32\as.exe --32 --strip-local-absolute "CODEGEN_FBFLTK_MAIN.asm" -o "CODEGEN_FBFLTK_MAIN.o"
compiling rc:               f:\FreeBasic\bin\win32\GoRC.exe /ni /nw /o /fo "CODEGEN_FBFLTK_RESOURCE.obj" "CODEGEN_FBFLTK_RESOURCE.rc"
linking:      f:\FreeBasic\bin\win32\ld.exe -m i386pe -o "FB-FLTK.exe" -subsystem windows "f:\FreeBasic\lib\win32\fbextra.x" --stack 1048576,1048576 -s -L "f:\FreeBasic\lib\win32" -L "." "f:\FreeBasic\lib\win32\crt2.o" "f:\FreeBasic\lib\win32\crtbegin.o" "f:\FreeBasic\lib\win32\fbrt0.o" "CODEGEN_FBFLTK_MAIN.o" "CODEGEN_FBFLTK_RESOURCE.obj" "-(" -lkernel32 -lgdi32 -lmsimg32 -luser32 -lversion -ladvapi32 -limm32 -lgdiplus -lole32 -luuid -loleaut32 -lcomctl32 -lcomdlg32 -lshell32 -lfltk-c-1.3.3-32 -lopengl32 -lfb -lgcc -lmsvcrt -lmingw32 -lmingwex -lmoldname -lgcc_eh "-)" "f:\FreeBasic\lib\win32\crtend.o"


So nothing wrong but it just does not work. Any ideas anyone.

Paul Squires

I have never used the FLTK library but I wonder if created controls must be built inside of a Fl_WindowNew window? FireFly uses a standard WinApi CreateWindowEx for its windows/forms.
Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

James Fuller

FLTK is a cross platform c++ library.
I believe Joshy has put a wrapper around it to allow Fb usage?

James

QuasiModule

#3
Thanks James, I am actually using Joshy's excellent wrapper. It works fine in the first example with a multitude of widgets. I think Paul has it right though. In the FLTK code everything is created in one sub along with the Window but note no use of a handle for anything except menu items in FLTK so the position in the code must decide which parent it is attached to.

Sub Create_Window_Main ()
'Window with buttons and Stuff:

    Window_Main = Fl_WindowNew (400, 200, "Button Test")

    Menu = Fl_Menu_BarNew (0, 0, 400, 20)
    Fl_Menu_Add (Menu, "File/New" ,,@flNewFile())
    Fl_Menu_Add (Menu, "File/Open" ,, @flOpenFile())
    Fl_Menu_Add (Menu, "File/Save" ,, @flSaveFile())
    Fl_Menu_Add (Menu, "File/Exit" ,, @flEndProgram())
    Fl_Menu_Add (Menu, "Edit" ,, @flDefault())
    Fl_Menu_Add (Menu, "Search" ,, @flDefault())
    Fl_Menu_Add (Menu, "View" ,, @flDefault())
    Fl_Menu_Add (Menu, "Tools" ,, @flDefault())
    Fl_Menu_Add (Menu, "Help/Info" ,, @flInfo())

    Box_text = Fl_BoxNew(150, 50, 100, 20, "Welcome to FLTK! with FreeBasic")
    Output_text = Fl_OutputNew (20, 140, 60, 20, "")
    Dial1 = Fl_DialNew (flDial1.flRight, flDial1.flTop, flDial1.flWidth, flDial1.flHeight, flDial1.flLabel)
    Dial2 = Fl_DialNew (flDial1.flRight+30, flDial1.flTop, flDial1.flWidth, flDial1.flHeight, "2")
    Dial3 = Fl_DialNew (flDial1.flRight+60, flDial1.flTop, flDial1.flWidth, flDial1.flHeight, "3")
    Fl_DialAngles(Dial1, 10, 350)
    Fl_DialAngles(Dial2, 10, 350)
    Fl_DialAngles(Dial3, 10, 350)
    Button1_Click = Fl_ButtonNew (160, 160, 100, 20, "Click me!")
    Button2_Click = Fl_ButtonNew (280, 160, 100, 20, "Not me!")
End Sub


This gets called as a first order of business by what appears to be the equivalent of main() in C/C++

'Main program:
Create_Window_Main ()
Fl_WidgetSetCallback0(Button1_Click, @Button1_Click_Event())
Fl_WidgetSetCallback0(Button2_Click, @Button2_Click_Event())
Fl_WidgetSetCallback0(Dial1, @Dial1_Event())
Fl_WidgetSetCallback0(Dial2, @Dial1_Event())
Fl_WidgetSetCallback0(Dial3, @Dial1_Event())
Fl_WindowShow(Window_Main)
Fl_Run


FireFly has FF_WinMain but as you can see I tried that and same result ... No button or errors

Function FF_WINMAIN( ByVal hInstance     as HINSTANCE, _
                     ByVal hPrevInstance as HINSTANCE, _
                     ByRef lpCmdLine     as String, _ 
                     ByVal iCmdShow      as Long ) as Long


    'FLButton1 = Fl_ButtonNew (230, 300, 70, 30, "FLTK Button")  ' Should be in front of Exit Button
    'Fl_WidgetSetCallback0(FLButton1, @FLButton1_Event())
   ' If this function returns TRUE (non-zero) then the actual WinMain will exit
   ' thus ending the program. You can do program initialization in this function.

   Function = False    'return TRUE if you want the program to end.

End Function


The FireFly create must create the window but then completes and goes out of scope I am guessing

Function FBFORM_WM_CREATE ( _
                          hWndForm as HWnd, _          ' handle of Form
                          ByVal UserData as Integer _  ' optional user defined value
                          ) as Long
        FLButton1 = Fl_ButtonNew (230, 300, 70, 30, "FLTK Button")  ' Should be in front of Exit Button
        Fl_WidgetSetCallback0(FLButton1, @FLButton1_Event())
   Function = 0   ' change according to your needs
End Function


Thing that really gets me is that I have a floating widget declaration and callback assignment here and between the compiler, assembler and linker I should be getting at least six pages of warnings and a minimum of ten errors for it. Watch what happens when I make a simple typo.

BTW FireFly v3.78 and FreeBasic Version 1.05.0