Author Topic: Gtk GUI Adventures  (Read 13115 times)

Offline John

  • Forum Support / SB Dev
  • Posts: 3597
    • ScriptBasic Open Source Project
Gtk GUI Adventures
« on: October 30, 2011, 08:39:55 AM »
Curently, PxBasic and PxPlus only offers a native GUI for Windows using their Nomads GUI builder. The goal of this project is to use GTK-Server (.so shared object) to script the replacement of PxPlus native Windows API high level directives with Gtk for Nomads.

NOMADS

If you would like to contribute to this effort with the hope that the author will incorporate this feature into the language as a plug-in for Linux, send me a e-mail support@scriptbasic.org to obtain an account on the forum.

Update

It has become painfully obvious that trying to enhance a commercial Basic language is a losing battle. Beside having to deal with everything externally due to no source access, the company takes issue to your efforts as taking revenue away from their offerings. The Gtk cross platform desktop GUI for PxPlus will be my last contribution to this language. The amount of grief it generates isn't worth it.

Validation

This customer spent days trying to resolve his issues connecting to a MySQL database with PxPlus. The resolution stated by a PxPlus dealer says it all.

Quote
I think I know what is happening:  you are using a v9 PxPLUS, I'm using a
v10 version.  The MySQL interface is a part of a v9 ProvideX Professional
licence, but in PxPLUS v9 it's not included in a Professional licence. If
you want to use the MySQL interface in v9 PxPLUS, you will need to buy the
PxPLUS MySQL package (#10004). Starting with PxPLUS v10, the MySQL interface
is included in a Professional licence, so upgrading to v10 would also solve
your problem.
« Last Edit: November 17, 2011, 10:18:01 AM by JRS »

Offline John

  • Forum Support / SB Dev
  • Posts: 3597
    • ScriptBasic Open Source Project
Gtk GUI Adventures
« Reply #1 on: October 30, 2011, 09:42:27 AM »
I created a generic libgtk-server.so shared object for Ubuntu 64 and attached it.  If you would like to build the same for your version of Linux, visit the GTK-Server Project Site and download the source.

« Last Edit: November 05, 2011, 08:47:35 AM by JRS »

Offline John

  • Forum Support / SB Dev
  • Posts: 3597
    • ScriptBasic Open Source Project
Gtk GUI Adventures
« Reply #2 on: October 30, 2011, 02:12:18 PM »
Quote
90% of programming jobs are in creating Line of Business software:

Economics 101: the price for anything (including you) is a function of the supply of it and demand for it.  Let’s talk about the demand side first.  Most software is not sold in boxes, available on the Internet, or downloaded from the App Store.  Most software is boring one-off applications in corporations, under-girding every imaginable facet of the global economy.  It tracks expenses, it optimizes shipping costs, it assists the accounting department in preparing projections, it helps design new widgets, it prices insurance policies, it flags orders for manual review by the fraud department, etc etc.  Software solves business problems.  Software often solves business problems despite being soul-crushingly boring and of minimal technical complexity.  For example, consider an internal travel expense reporting form.  Across a company with 2,000 employees, that might save 5,000 man-hours a year (at an average fully-loaded cost of $50 an hour) versus handling expenses on paper, for a savings of $250,000 a year.  It does not matter to the company that the reporting form is the world’s simplest CRUD app, it only matters that it either saves the company costs or generates additional revenue.

There are companies which create software which actually gets used by customers, which describes almost everything that you probably think of when you think of software.  It is unlikely that you will work at one unless you work towards making this happen.  Even if you actually work at one, many of the programmers there do not work on customer-facing software, either.

If this is true, companies will be looking at Linux and the vast offering of open source solutions to save money or increase revenues.

Don't assume just because you don't have to pay for the application and have free access to the code to change if you wish that open source software is free. Someone needs to maintain it and keep it current with the OS (community contributions) and support is either peer or pay depending on the popularity or business value.
« Last Edit: November 02, 2011, 09:00:51 AM by JRS »

Offline John

  • Forum Support / SB Dev
  • Posts: 3597
    • ScriptBasic Open Source Project
Gtk GUI Adventures
« Reply #3 on: October 31, 2011, 08:33:28 PM »
I created a Ubuntu 32 bit Amazon EC2 instance and compiled gtk-server as a shared object to be used with the Ubuntu 32 bit version of PxPlus. When I have time I will show a Glade based GUI example running under PxPlus. I hate wasting my time and maybe someone will find this of value. The negative karma I get from most of the ProvideX list is disheartening.
« Last Edit: November 02, 2011, 09:01:41 AM by JRS »

aurel

  • Guest
Gtk GUI Adventures
« Reply #4 on: November 01, 2011, 01:05:11 AM »
John i really don't know why you wasting your time with PWX or Provide basic
(what is the real name anyway ???).?
« Last Edit: November 05, 2011, 08:48:10 AM by JRS »

Offline John

  • Forum Support / SB Dev
  • Posts: 3597
    • ScriptBasic Open Source Project
Gtk GUI Adventures
« Reply #5 on: November 01, 2011, 05:02:18 PM »
I was able to verify that the gtk-server.so I built for Ubuntu 32 works with PxPlus version 10. My plan is to convert the ScriptBasic version of the Glade based calculator example to PxBasic. At that point with the Gtk definitions I already built and the Glade interface, one should be able to Use PxBasic/PxPlus/ProvideX to build native GUI applications under Linux and potentially OS X.

I'll call it my contribution to the PxPlus Linux developer's group with the hope a few brave souls will give it a try.
« Last Edit: November 05, 2011, 08:48:38 AM by JRS »

Offline John

  • Forum Support / SB Dev
  • Posts: 3597
    • ScriptBasic Open Source Project
Gtk GUI Adventures
« Reply #6 on: November 01, 2011, 09:00:58 PM »
I decided to take a break from getting the PxPlus version of the calculator working and spent some time freshing up my Gtk installation under Windows XP. (in a VirtualBox) I really like the Gtk preference tool. It has a bunch of themes to choose from. I decided on Clear Looks to match my Ubuntu Linux theme.

« Last Edit: November 02, 2011, 09:02:05 AM by JRS »

Offline John

  • Forum Support / SB Dev
  • Posts: 3597
    • ScriptBasic Open Source Project
Gtk GUI Adventures
« Reply #7 on: November 01, 2011, 11:39:45 PM »
Here is Peter's on-line dictionary Gtk example running under Linux and Windows in ScriptBasic. The same SB script runs untouched on either platform.

Ubuntu Linux


Windows XP


Code: [Select]
#!/usr/bin/scriba
REM ************************************************************************
REM
REM DICT client to lookup words
REM Using the HTML widgets of the Scriptbasic wrapper
REM
REM Expand the GTK namespace if you feel necessary!
REM Feb. 10, 2006 - PvE.
REM
REM ************************************************************************

REM Import GTK definition first
IMPORT gtk.bas

GLOBAL CONST nl = "\n"
GLOBAL CONST title = "Thesaurus!"

REM Create main window
mainwin = GTK::window(title, 500, 450)

REM Create droplist part
frame1 = GTK::frame(" Servers ", 255, 65)
GTK::attach(frame1, mainwin, 10, 10)
servers[0] = "dict.org"
servers[1] = "dict.aioe.org"
servers[2] = "dict.tugraz.at"
servers[3] = "mova.org"
servers[4] = "dict.tu-chemnitz.de"
servers[5] = "test.dict.org"
servers[6] = "dict.trit.org"
servers[7] = "dict.die.net"
servers[8] = "www.lojban.org"
servers[9] = "dict.arabeyes.org"
servers[10] = "muktaka.dyndns.org"
servers[11] = "dict.saugus.net"
servers[12] = "dictionary.bishopston.net"
servers[13] = "la-sorciere.de"
servers[14] = "es.dict.org"
servers[15] = "lividict.org"
servers[16] = "mali.geekcorps.org"
servers[17] = "dione.zcu.cz"
servers[18] = "dict.kurtwerks.com"
servers[19] = "madison.onespeeddave.com"
drop = GTK::droplist(servers, 165, 35)
GTK::attach(drop, mainwin, 20, 30)
fetch = GTK::button("Fetch", 60, 35)
GTK::attach(fetch, mainwin, 195, 30)

REM Create control panel
frame2 = GTK::frame(" Control ", 210, 65)
GTK::attach(frame2, mainwin, 275, 10)
about = GTK::button("About", 60, 35)
GTK::attach(about, mainwin, 285, 30)
clear = GTK::button("Clear", 60, 35)
GTK::attach(clear, mainwin, 350, 30)
exbut = GTK::button("Exit", 60, 35)
GTK::attach(exbut, mainwin, 415, 30)

REM Create dictionary panel
frame3 = GTK::frame(" Dictionaries ", 480, 125)
GTK::attach(frame3, mainwin, 10, 85)
dat[0] = ""
list = GTK::list(dat, 460, 90)
GTK::attach(list, mainwin, 20, 110)
GTK::bg_color(list, 49152, 49152, 49152)

REM Create text part
frame4 = GTK::frame(" Translation ", 480, 190)
GTK::attach(frame4, mainwin, 10, 220)
text = GTK::text(460, 155)
GTK::attach(text, mainwin, 20, 245)
GTK::disable(text)
GTK::bg_color(text, 49152, 49152, 49152)

REM Create entry and lookup button
entry = GTK::entry(360, 25)
GTK::attach(entry, mainwin, 10, 420)
utf8 = GTK::check("UTF-8", 60, 30)
GTK::attach(utf8, mainwin, 430, 415)
dflt = GTK::check("All", 40, 30)
GTK::attach(dflt, mainwin, 380, 415)

REM Create about window
aboutwin = GTK::window("About", 300, 120)
GTK::hide(aboutwin)
label1 = GTK::label("Demo program with the GTK module.", 280, 20)
GTK::attach(label1, aboutwin, 10, 5)
GTK::fg_color(label1, 32768, 0, 0)
label2 = GTK::label("Using " & GTK::version() & " with Scriptbasic.", 280, 20)
GTK::attach(label2, aboutwin, 10, 25)
GTK::fg_color(label2, 0, 0, 32768)
label3 = GTK::label("(C) Peter van Eerten - February 6, 2006", 280, 20)
GTK::attach(label3, aboutwin, 10, 45)
GTK::fg_color(label3, 0, 32768, 0)
okbut = GTK::button("OK", 60, 35)
GTK::attach(okbut, aboutwin, 120, 80)

REM Mainloop
REPEAT
REM Put focus to entry
GTK::focus(entry)
REM Wait for event
action = GTK::event()
REM Get all dictionaries of server
IF action = fetch THEN CALL Get_Dicts
REM Get meaning of word
IF action = entry THEN CALL Lookup_Word
REM Clear all widgets
IF action = clear THEN CALL Clear_All
REM Show about window
IF action = about THEN GTK::show(aboutwin)
REM Hide about window
IF action = okbut OR action = aboutwin THEN GTK::hide(aboutwin)

UNTIL action = mainwin OR action = exbut

END

REM ************************************************************************

SUB Get_Dicts

LOCAL dat$, total, count

ON ERROR GOTO G_NetError

OPEN GTK::get_text(drop) & ":2628" FOR socket AS 1

PRINT#1,"SHOW DB\n"

LINE INPUT#1, dat$
LINE INPUT#1, dat$

count = 0
WHILE LEFT(dat$, 1) <> "."
LINE INPUT#1, dat$
dat$ = REPLACE(dat$, CHR$(34), CHR$(92) & CHR$(34))
IF LEFT$(dat$, 1) <> "." THEN total[count] = TRIM(dat$)
count+=1
WEND
PRINT#1,"QUIT\n"
CLOSE 1

GTK::fg_color(list, 0, 0, 65535)
GTK::set_text(list, total)

EXIT SUB

G_NetError:
dat$[0] = "Server not available!"
GTK::fg_color(list, 65535, 0, 0)
GTK::set_text(list, dat$)

END SUB

REM ************************************************************************

SUB Lookup_Word

LOCAL dict$, dat$, total$, info$

GTK::set_text(mainwin, title & " - \\\"" & GTK::get_text(entry) & "\\\"")
GTK::fg_color(text, 0, 32768, 0)
GTK::set_text(text, "Fetching....")
GTK::async()

ON ERROR GOTO L_NetError

dict$ = LEFT(GTK::get_text(list), INSTR(GTK::get_text(list), " "))

OPEN GTK::get_text(drop) & ":2628" FOR socket AS 1

IF GTK::get_value(dflt) THEN
PRINT#1,"DEFINE * " & GTK::get_text(entry) & "\n"
ELSE
PRINT#1,"DEFINE " & dict$ & " " & GTK::get_text(entry) & "\n"
END IF

REPEAT
LINE INPUT#1, dat$
dat$ = REPLACE(dat$, CHR$(34), CHR$(92) & CHR$(34))
IF LEFT(dat$, 3) = "151" THEN
total$ &= "------------------------------\n"
total$ &= RIGHT(dat$, LEN(dat$) - LEN(GTK::get_text(entry)) - 9)
total$ &= "------------------------------\n"
REPEAT
LINE INPUT#1, info$
info$ = REPLACE(info$, CHR$(34), CHR$(92) & CHR$(34))
IF LEFT(info$, 1) <> "." THEN total$ &= TRIM(info$) & nl
UNTIL LEFT(info$, 1) = "."
total$ &= "\n"
END IF
UNTIL LEFT(dat$, 3) = "250" OR VAL(LEFT(dat$, 3)) > 499

PRINT#1,"QUIT\n"
CLOSE 1

IF LEFT(dat$, 3) = "552" THEN
total$ = "No match found."
GTK::fg_color(text, 65535, 0, 0)
ELSE IF LEFT(dat$, 3) = "501" THEN
total$ = "Select a dictionary first!"
GTK::fg_color(text, 65535, 0, 0)
ELSE IF LEFT(dat$, 3) = "550" THEN
total$ = "Invalid database!"
GTK::fg_color(text, 65535, 0, 0)
ELSE
GTK::fg_color(text, 0, 0, 49152)
END IF

IF GTK::get_value(utf8) THEN
GTK::set_text(text, GTK::UTF8(total$))
ELSE
GTK::set_text(text, total$)
END IF
GTK::set_value(text, 0)

EXIT SUB

L_NetError:
dat$[0] = "Could not lookup word!"
GTK::fg_color(list, 65535, 0, 0)
GTK::set_text(list, dat$)

END SUB

REM ************************************************************************

SUB Clear_All

LOCAL ar$

ar$[0] = ""
GTK::set_text(list, ar$)
GTK::set_text(text, "")

END SUB

REM ************************************************************************
« Last Edit: November 02, 2011, 09:02:18 AM by JRS »

Offline John

  • Forum Support / SB Dev
  • Posts: 3597
    • ScriptBasic Open Source Project
Gtk GUI Adventures
« Reply #8 on: November 02, 2011, 11:25:51 AM »
I was able to get the Glade XML project based calculator demo running under Windows.


Linux


Windows XP


Code: [Select]
' Gtk Calculator

IMPORT gtk.bas
gtk_server_cfg("-cfg=C:\\GTK-server\\gtk-server.cfg")

' Initialize calculator state
calculator_state = 0

' Initialize calculator cache
calculator_cache = 0

' Initialize last calculator action
calculator_action = 0

' Initialize MEM function
mem = 0

' Process the action
SUB Handle_Operator(entry)
  LOCAL value
  IF calculator_state = 0 THEN
    IF calculator_action = 1 THEN
      value = gtk::gtk("gtk_entry_get_text " & entry)
      calculator_cache += value
      gtk::gtk("gtk_entry_set_text " & entry & " " & calculator_cache)
    ELSE IF calculator_action = 2 THEN
      value = gtk::gtk("gtk_entry_get_text " & entry)
      calculator_cache -= value
      gtk::gtk("gtk_entry_set_text " & entry & " " & calculator_cache)
    ELSE IF calculator_action = 3 THEN
      value = gtk::gtk("gtk_entry_get_text " & entry)
      calculator_cache *= value
      gtk::gtk("gtk_entry_set_text " & entry & " " & calculator_cache)
    ELSE IF calculator_action = 4 THEN
      value = gtk::gtk("gtk_entry_get_text " & entry)
      IF value = 0 THEN
        gtk::gtk("gtk_entry_set_text " & entry & " ERROR")
      ELSE
        calculator_cache /= value
        gtk::gtk("gtk_entry_set_text " & entry & " " & calculator_cache)
      END IF
    END IF
  END IF
END SUB

SUB Calc_Exit
  gtk::gtk("gtk_server_exit")
END SUB

' All button actions here
SUB Button_Memread(entry, widget)
  calculator_state = 0
  calculator_cache = gtk::gtk("gtk_entry_get_text " & entry)
  gtk::gtk("gtk_entry_set_text " & entry & " " & mem)
END SUB

SUB Button_Memadd(entry, widget)
  mem = gtk::gtk("gtk_entry_get_text " & entry)
END SUB

SUB Button_C(entry, widget)
  gtk::gtk("gtk_entry_set_text " & entry & " 0")
END SUB

SUB Button_CE(entry, widget)
  calculator_state = 0
  calculator_action = 0
  calculator_cache = 0
  mem = 0
  gtk::gtk("gtk_entry_set_text " & entry & " 0")
END SUB

SUB Button_Add(entry, widget)
    Handle_Operator(entry)
    calculator_action = 1
    calculator_state += 1
END SUB

SUB Button_Subtract(entry, widget)
    Handle_Operator(entry)
    calculator_action = 2
    calculator_state += 1
END SUB

SUB Button_Multiply(entry, widget)
    Handle_Operator(entry)
    calculator_action = 3
    calculator_state += 1
END SUB

SUB Button_Divide(entry, widget)
    Handle_Operator(entry)
    calculator_action = 4
    calculator_state += 1
END SUB

SUB Button_Equals(entry, widget)
    Handle_Operator(entry)
    calculator_action = 0
    calculator_state += 1
END SUB

SUB Button_Clicked(entry, widget)
    LOCAL button, text
    button = gtk::gtk("gtk_button_get_label " & widget)
    text = gtk::gtk("gtk_entry_get_text " & entry)
    IF text = "0" OR calculator_state > 0 THEN
      calculator_cache = text
      gtk::gtk("gtk_entry_set_text " & entry & " " & button)
    ELSE
      gtk::gtk("gtk_entry_set_text " & entry & " " & text & button)
    END IF
    calculator_state = 0
END SUB

' Main program
gtk::gtk("gtk_init NULL NULL")

gtk::gtk("glade_init")
' xml = gtk::gtk("glade_xml_new_from_buffer " & Calc_XML & " " & LEN(Calc_XML) & " 0 0")
xml = gtk::gtk("glade_xml_new \"calc.glade\" NULL NULL")
gtk::gtk("glade_xml_signal_autoconnect " & xml)

' Calc_Exit
win = gtk::gtk("glade_xml_get_widget " &  xml & " window")
gtk::gtk("gtk_server_connect " & win & " delete-event window")

' Entry
ent = gtk::gtk("glade_xml_get_widget " & xml & " entry")

' Button_Clicked
but1 = gtk::gtk("glade_xml_get_widget " &  xml & " button1")
gtk::gtk("gtk_server_connect " & but1 & " clicked button1")
but2 = gtk::gtk("glade_xml_get_widget " &  xml & " button2")
gtk::gtk("gtk_server_connect " & but2 & " clicked button2")
but3 = gtk::gtk("glade_xml_get_widget " &  xml & " button3")
gtk::gtk("gtk_server_connect " & but3 & " clicked button3")
but4 = gtk::gtk("glade_xml_get_widget " &  xml & " button4")
gtk::gtk("gtk_server_connect " & but4 & " clicked button4")
but5 = gtk::gtk("glade_xml_get_widget " &  xml & " button5")
gtk::gtk("gtk_server_connect " & but5 & " clicked button5")
but6 = gtk::gtk("glade_xml_get_widget " &  xml & " button6")
gtk::gtk("gtk_server_connect " & but6 & " clicked button6")
but7 = gtk::gtk("glade_xml_get_widget " &  xml & " button7")
gtk::gtk("gtk_server_connect " & but7 & " clicked button7")
but8 = gtk::gtk("glade_xml_get_widget " &  xml & " button8")
gtk::gtk("gtk_server_connect " & but8 & " clicked button8")
but9 = gtk::gtk("glade_xml_get_widget " &  xml & " button9")
gtk::gtk("gtk_server_connect " & but9 & " clicked button9")
but0 = gtk::gtk("glade_xml_get_widget " &  xml & " button0")
gtk::gtk("gtk_server_connect " & but0 & " clicked button0")

' Button_Add
butADD = gtk::gtk("glade_xml_get_widget " &  xml & " buttonAdd")
gtk::gtk("gtk_server_connect " & butADD & " clicked buttonAdd")

' Button_Subtract
butSUB = gtk::gtk("glade_xml_get_widget " &  xml & " buttonMinus")
gtk::gtk("gtk_server_connect " & butSUB & " clicked buttonMinus")

' Button_Multiply
butMUL = gtk::gtk("glade_xml_get_widget " &  xml & " buttonMul")
gtk::gtk("gtk_server_connect " & butMUL & " clicked buttonMul")

' Button_Divide
butDIV = gtk::gtk("glade_xml_get_widget " &  xml & " buttonDiv")
gtk::gtk("gtk_server_connect " & butDIV & " clicked buttonDiv")

' Button_Equals
butEQ = gtk::gtk("glade_xml_get_widget " &  xml & " buttonEq")
gtk::gtk("gtk_server_connect " & butEQ & " clicked buttonEq")

' Button_C
butC = gtk::gtk("glade_xml_get_widget " &  xml & " buttonC")
gtk::gtk("gtk_server_connect " & butC & " clicked buttonC")

' Button_CE
butCE = gtk::gtk("glade_xml_get_widget " &  xml & " buttonCE")
gtk::gtk("gtk_server_connect " & butCE & " clicked buttonCE")

' Button_Memadd
memadd = gtk::gtk("glade_xml_get_widget " &  xml & " buttonMemadd")
gtk::gtk("gtk_server_connect " & memadd & " clicked buttonMemadd")

' Button_Memread
memread = gtk::gtk("glade_xml_get_widget " &  xml & " buttonMemread")
gtk::gtk("gtk_server_connect " & memread & " clicked buttonMemread")

REPEAT
  event = gtk::gtk("gtk_server_callback wait")
  IF event = "button1" THEN Button_Clicked(ent, but1)
  IF event = "button2" THEN Button_Clicked(ent, but2)
  IF event = "button3" THEN Button_Clicked(ent, but3)
  IF event = "button4" THEN Button_Clicked(ent, but4)
  IF event = "button5" THEN Button_Clicked(ent, but5)
  IF event = "button6" THEN Button_Clicked(ent, but6)
  IF event = "button7" THEN Button_Clicked(ent, but7)
  IF event = "button8" THEN Button_Clicked(ent, but8)
  IF event = "button9" THEN Button_Clicked(ent, but9)
  IF event = "button0" THEN Button_Clicked(ent, but0)
  IF event = "buttonAdd" THEN Button_Add(ent, butADD)
  IF event = "buttonMinus" THEN Button_Subtract(ent, butSUB)
  IF event = "buttonMul" THEN Button_Multiply(ent, butMUL)
  IF event = "buttonDiv" THEN Button_Divide(ent, butDIV)
  IF event = "buttonEq" THEN Button_Equals(ent, butEQ)
  IF event = "buttonC" THEN Button_C(ent, butC)
  IF event = "buttonCE" THEN Button_CE(ent, butCE)
  IF event = "buttonMemadd" THEN Button_Memadd(ent, memadd)
  IF event = "buttonMemread" THEN Button_Memread(ent, memread)
UNTIL event = "window"

calc.glade
Code: [Select]
<?xml version="1.0"?>
<glade-interface>
  <widget class="GtkWindow" id="window">
    <property name="width_request">250</property>
    <property name="height_request">225</property>
    <property name="visible">True</property>
    <property name="title" translatable="yes">SBGtk Calculator</property>
    <property name="resizable">False</property>
    <property name="window_position">center</property>
    <property name="default_width">264</property>
    <property name="default_height">248</property>
    <property name="icon_name">calc</property>
    <child>
      <widget class="GtkTable" id="table1">
        <property name="visible">True</property>
        <property name="n_rows">5</property>
        <property name="n_columns">5</property>
        <property name="homogeneous">True</property>
        <child>
          <widget class="GtkButton" id="buttonMemadd">
            <property name="label" translatable="yes">M+</property>
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="receives_default">False</property>
          </widget>
          <packing>
            <property name="left_attach">3</property>
            <property name="right_attach">4</property>
            <property name="top_attach">4</property>
            <property name="bottom_attach">5</property>
            <property name="x_padding">4</property>
            <property name="y_padding">8</property>
          </packing>
        </child>
        <child>
          <widget class="GtkEntry" id="entry">
            <property name="visible">True</property>
            <property name="sensitive">False</property>
            <property name="editable">False</property>
            <property name="xalign">1</property>
          </widget>
          <packing>
            <property name="right_attach">5</property>
            <property name="x_padding">4</property>
          </packing>
        </child>
        <child>
          <widget class="GtkButton" id="button1">
            <property name="label" translatable="yes">1</property>
            <property name="width_request">0</property>
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="receives_default">False</property>
          </widget>
          <packing>
            <property name="top_attach">1</property>
            <property name="bottom_attach">2</property>
            <property name="x_padding">4</property>
            <property name="y_padding">8</property>
          </packing>
        </child>
        <child>
          <widget class="GtkButton" id="button3">
            <property name="label" translatable="yes">3</property>
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="receives_default">False</property>
          </widget>
          <packing>
            <property name="left_attach">2</property>
            <property name="right_attach">3</property>
            <property name="top_attach">1</property>
            <property name="bottom_attach">2</property>
            <property name="x_padding">4</property>
            <property name="y_padding">8</property>
          </packing>
        </child>
        <child>
          <widget class="GtkButton" id="buttonC">
            <property name="label" translatable="yes">C</property>
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="receives_default">False</property>
          </widget>
          <packing>
            <property name="left_attach">3</property>
            <property name="right_attach">4</property>
            <property name="top_attach">1</property>
            <property name="bottom_attach">2</property>
            <property name="x_padding">4</property>
            <property name="y_padding">8</property>
          </packing>
        </child>
        <child>
          <widget class="GtkButton" id="buttonCE">
            <property name="label" translatable="yes">CE</property>
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="receives_default">False</property>
          </widget>
          <packing>
            <property name="left_attach">4</property>
            <property name="right_attach">5</property>
            <property name="top_attach">1</property>
            <property name="bottom_attach">2</property>
            <property name="x_padding">4</property>
            <property name="y_padding">8</property>
          </packing>
        </child>
        <child>
          <widget class="GtkButton" id="button4">
            <property name="label" translatable="yes">4</property>
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="receives_default">False</property>
          </widget>
          <packing>
            <property name="top_attach">2</property>
            <property name="bottom_attach">3</property>
            <property name="x_padding">4</property>
            <property name="y_padding">8</property>
          </packing>
        </child>
        <child>
          <widget class="GtkButton" id="button5">
            <property name="label" translatable="yes">5</property>
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="receives_default">False</property>
          </widget>
          <packing>
            <property name="left_attach">1</property>
            <property name="right_attach">2</property>
            <property name="top_attach">2</property>
            <property name="bottom_attach">3</property>
            <property name="x_padding">4</property>
            <property name="y_padding">8</property>
          </packing>
        </child>
        <child>
          <widget class="GtkButton" id="button6">
            <property name="label" translatable="yes">6</property>
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="receives_default">False</property>
          </widget>
          <packing>
            <property name="left_attach">2</property>
            <property name="right_attach">3</property>
            <property name="top_attach">2</property>
            <property name="bottom_attach">3</property>
            <property name="x_padding">4</property>
            <property name="y_padding">8</property>
          </packing>
        </child>
        <child>
          <widget class="GtkButton" id="buttonAdd">
            <property name="label" translatable="yes">+</property>
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="receives_default">False</property>
          </widget>
          <packing>
            <property name="left_attach">3</property>
            <property name="right_attach">4</property>
            <property name="top_attach">2</property>
            <property name="bottom_attach">3</property>
            <property name="x_padding">4</property>
            <property name="y_padding">8</property>
          </packing>
        </child>
        <child>
          <widget class="GtkButton" id="buttonMinus">
            <property name="label" translatable="yes">-</property>
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="receives_default">False</property>
          </widget>
          <packing>
            <property name="left_attach">4</property>
            <property name="right_attach">5</property>
            <property name="top_attach">2</property>
            <property name="bottom_attach">3</property>
            <property name="x_padding">4</property>
            <property name="y_padding">8</property>
          </packing>
        </child>
        <child>
          <widget class="GtkButton" id="button7">
            <property name="label" translatable="yes">7</property>
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="receives_default">False</property>
          </widget>
          <packing>
            <property name="top_attach">3</property>
            <property name="bottom_attach">4</property>
            <property name="x_padding">4</property>
            <property name="y_padding">8</property>
          </packing>
        </child>
        <child>
          <widget class="GtkButton" id="button8">
            <property name="label" translatable="yes">8</property>
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="receives_default">False</property>
          </widget>
          <packing>
            <property name="left_attach">1</property>
            <property name="right_attach">2</property>
            <property name="top_attach">3</property>
            <property name="bottom_attach">4</property>
            <property name="x_padding">5</property>
            <property name="y_padding">8</property>
          </packing>
        </child>
        <child>
          <widget class="GtkButton" id="button9">
            <property name="label" translatable="yes">9</property>
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="receives_default">False</property>
          </widget>
          <packing>
            <property name="left_attach">2</property>
            <property name="right_attach">3</property>
            <property name="top_attach">3</property>
            <property name="bottom_attach">4</property>
            <property name="x_padding">4</property>
            <property name="y_padding">8</property>
          </packing>
        </child>
        <child>
          <widget class="GtkButton" id="buttonMul">
            <property name="label" translatable="yes">*</property>
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="receives_default">False</property>
          </widget>
          <packing>
            <property name="left_attach">3</property>
            <property name="right_attach">4</property>
            <property name="top_attach">3</property>
            <property name="bottom_attach">4</property>
            <property name="x_padding">4</property>
            <property name="y_padding">8</property>
          </packing>
        </child>
        <child>
          <widget class="GtkButton" id="buttonDiv">
            <property name="label" translatable="yes">/</property>
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="receives_default">False</property>
          </widget>
          <packing>
            <property name="left_attach">4</property>
            <property name="right_attach">5</property>
            <property name="top_attach">3</property>
            <property name="bottom_attach">4</property>
            <property name="x_padding">4</property>
            <property name="y_padding">8</property>
          </packing>
        </child>
        <child>
          <widget class="GtkButton" id="button0">
            <property name="label" translatable="yes">0</property>
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="receives_default">False</property>
          </widget>
          <packing>
            <property name="top_attach">4</property>
            <property name="bottom_attach">5</property>
            <property name="x_padding">4</property>
            <property name="y_padding">8</property>
          </packing>
        </child>
        <child>
          <widget class="GtkButton" id="buttonMemread">
            <property name="label" translatable="yes">MR</property>
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="receives_default">False</property>
          </widget>
          <packing>
            <property name="left_attach">4</property>
            <property name="right_attach">5</property>
            <property name="top_attach">4</property>
            <property name="bottom_attach">5</property>
            <property name="x_padding">4</property>
            <property name="y_padding">8</property>
          </packing>
        </child>
        <child>
          <widget class="GtkButton" id="buttonEq">
            <property name="label" translatable="yes">=</property>
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="receives_default">False</property>
          </widget>
          <packing>
            <property name="left_attach">1</property>
            <property name="right_attach">3</property>
            <property name="top_attach">4</property>
            <property name="bottom_attach">5</property>
            <property name="x_padding">4</property>
            <property name="y_padding">8</property>
          </packing>
        </child>
        <child>
          <widget class="GtkButton" id="button2">
            <property name="label" translatable="yes">2</property>
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="receives_default">False</property>
          </widget>
          <packing>
            <property name="left_attach">1</property>
            <property name="right_attach">2</property>
            <property name="top_attach">1</property>
            <property name="bottom_attach">2</property>
            <property name="x_padding">4</property>
            <property name="y_padding">8</property>
          </packing>
        </child>
      </widget>
    </child>
  </widget>
</glade-interface>

FWIW

This should work under PxBasic/PxPlus (Windows/Linux/Mac) as well.
« Last Edit: November 02, 2011, 11:30:10 AM by JRS »

Offline John

  • Forum Support / SB Dev
  • Posts: 3597
    • ScriptBasic Open Source Project
Gtk GUI Adventures
« Reply #9 on: November 03, 2011, 12:58:43 PM »
I was able to get PxBasic 10 under Windows to work with GTK-Server.



Code: [Select]
! Glade Hello World

gtk_lib = DLL(ADDR "gtk-server.dll")

ok=DLL(gtk_lib,"gtk","gtk_server_cfg-cfg=/GTK-server/gtk-server.cfg"+$00$)

! Initialize GTK & Glade
ok=DLL(gtk_lib,"gtk","gtk_init NULL NULL"+$00$)
ok=DLL(gtk_lib,"gtk","glade_init"+$00$)

! Load and show Glade defined window
strptr = DLL(gtk_lib,"gtk","glade_xml_new "+quo+"hello.glade"+quo+" NULL NULL"+$00$)
xml$=MEM(strptr,0)
ok=DLL(gtk_lib,"gtk","glade_xml_signal_autoconnect "+xml$+$00$)
! Get window ID and define window close event
strptr=DLL(gtk_lib,"gtk","glade_xml_get_widget "+xml$+" window1"+$00$)
gtkwin$=MEM(strptr,0)
ok=DLL(gtk_lib,"gtk","gtk_server_connect "+gtkwin$+" delete-event window"+$00$)

! Event Handler
REPEAT
  strptr=DLL(gtk_lib,"gtk","gtk_server_callback WAIT"+$00$)
  this_event$ = MEM(strptr,0)
UNTIL this_event$ = "window"

ok=DLL(gtk_lib,"gtk","gtk_widget_destroy "+gtkwin$+$00$)
ok=DLL(DROP gtk_lib)

hello.glade
Code: [Select]
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">

<glade-interface>

<widget class="GtkWindow" id="window1">
  <property name="visible">True</property>
  <property name="title" translatable="yes">Hello</property>
  <property name="type">GTK_WINDOW_TOPLEVEL</property>
  <property name="window_position">GTK_WIN_POS_NONE</property>
  <property name="modal">False</property>
  <property name="default_width">400</property>
  <property name="default_height">350</property>
  <property name="resizable">True</property>
  <property name="destroy_with_parent">False</property>
  <property name="decorated">True</property>
  <property name="skip_taskbar_hint">False</property>
  <property name="skip_pager_hint">False</property>
  <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
  <property name="focus_on_map">True</property>
  <property name="urgency_hint">False</property>

  <child>
    <widget class="GtkFixed" id="fixed1">
      <property name="visible">True</property>

      <child>
<widget class="GtkLabel" id="label1">
 <property name="width_request">122</property>
 <property name="height_request">17</property>
 <property name="visible">True</property>
 <property name="label" translatable="yes">Hello PxBasic!</property>
 <property name="use_underline">False</property>
 <property name="use_markup">False</property>
 <property name="justify">GTK_JUSTIFY_LEFT</property>
 <property name="wrap">False</property>
 <property name="selectable">False</property>
 <property name="xalign">0.5</property>
 <property name="yalign">0.5</property>
 <property name="xpad">0</property>
 <property name="ypad">0</property>
 <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
 <property name="width_chars">-1</property>
 <property name="single_line_mode">False</property>
 <property name="angle">0</property>
</widget>
<packing>
 <property name="x">128</property>
 <property name="y">128</property>
</packing>
      </child>
    </widget>
  </child>
</widget>

</glade-interface>
« Last Edit: November 05, 2011, 08:54:07 AM by JRS »

Offline John

  • Forum Support / SB Dev
  • Posts: 3597
    • ScriptBasic Open Source Project
Gtk GUI Adventures - Resouces
« Reply #10 on: November 03, 2011, 02:37:54 PM »
Windows Gtk Development Resources

« Last Edit: November 03, 2011, 02:55:16 PM by JRS »

Offline John

  • Forum Support / SB Dev
  • Posts: 3597
    • ScriptBasic Open Source Project
Gtk GUI Adventures
« Reply #11 on: November 03, 2011, 08:56:16 PM »
Chris sent me his first pass working with GTK-Server. (TCP)

Quote
John,

Here is a first pass attempt at the example from gtk-server.org (using
PxBasic, Gtk-server and Gtk2 Runtime on Windows Vista):

Code: [Select]
0010 BEGIN
0020 OPEN (HFN)"[tcp];65000"; LET CHAN=LFO
0030 INVOKE "C:\GTK-server\gtk-server.exe -sock=127.0.0.1:65000"
0040 READ RECORD (CHAN,TIM=60,ERR=CONN_FAILURE)X$; IF X$<>"" THEN GOTO CONN_FAILURE
0050 LET JUNK$=FN_GTK$("gtk_init NULL NULL")
0060 LET HWIN$=FN_GTK$("gtk_window_new 0")
0070 LET JUNK$=FN_GTK$("gtk_window_set_title "+HWIN$+"""PxBasic GTK-server""")
0080 LET HTBL$=FN_GTK$("gtk_table_new 10 10 1")
0090 LET JUNK$=FN_GTK$("gtk_container_add "+HWIN$+" "+HTBL$)
0100 LET HBUT$=FN_GTK$("gtk_button_new_with_label ""Click to Quit""")
0110 LET JUNK$=FN_GTK$("gtk_table_attach_defaults "+HTBL$+" "+HBUT$+" 5 9 5 9")
0120 LET JUNK$=FN_GTK$("gtk_widget_show_all "+HWIN$)
0130 LET EVENT$=""
0140 WHILE CSE(EVENT$,HBUT$,HWIN$)=0
0150 LET EVENT$=FN_GTK$("gtk_server_callback wait")
0160 WEND
0170 LET JUNK$=FN_GTK$("gtk_server_exit",ERR=*NEXT)
0180 DONE:
0190 END
0200 CONN_FAILURE:
0210 PRINT "Connection failure"
0220 GOTO DONE
0230 GTK:
0240 DEF FN_GTK$(LOCAL COMMAND$)
0250 LOCAL X$
0260 WRITE RECORD (CHAN)COMMAND$
0270 LET X$=""; READ RECORD (CHAN,TIM=60)X$
0280 RETURN X$
0290 END DEF



In my opinion, using TCP/IP has more promise than using the direct DLL
method and is easier to understand (at least for me).  In addition, it
will ultimately provide for separation between the client and the server
(similar to the Windx model) which is something I care about.  It would
be interesting to run this on non-Windows platforms.  Doing so should be
just a matter of changing the location of the gtk-server executable on
line 30.

Cheers,

Chris Kukuchka
Sequoia Group, Inc.
« Last Edit: November 05, 2011, 08:53:46 AM by JRS »