THIS DOCUMENT IS IN THE ALPHA STAGE!
That means it is still skeletal and there are many incomplete sections. It is up simply to serve as a stimulant for further discourse. That means I want your feedback! What do you want to know? What do you already know? Let me know!
With that, read on...
Hopefully you've familiarized yourself with the basics of GUI application programming in Euphoria. The beginning of this book will be library-generic, meaning we'll cover generic GUI-programming topics. The second part of the book will get specific, and we'll choose a library to use at that time.
This book will serve as an advanced look at GUI programming in Euphoria. We explored a few libraries in Part 1. Now, we're going to do more than just push a few buttons and pop-up a messagebox. We want to take it to the next level.
If you'd like to print out this entire document, return to the Table of Contents and click the "Print Book" link at the bottom of the page. It will create a version of this entire document that you can print from your web browser.
If you have any comments or questions regarding anything you read here, or you want to contribute to this document, please send them to me. This book is just a start and it is ready for your input! I expect it will be dynamic, never really finished, as every day these Euphoria GUI packages are improved to make creating Euphoria GUI programs that much easier.
Also, check the Euphoria Code Archive for lots of code for GUI programming on a variety of platforms.
It's wise to have a plan of action when developing a GUI application. Regardless of what programming language you use and regardless of what GUI library you use, getting down on paper a solidified idea of what your application will do and what it will look like is 80% of the battle. Coding is the easy part.
So, what does an efficient approach to GUI programming look like? In outline form, it's simply a set of steps that builds on the prior foundation. These steps, taken sequentially, can virtually guarantee you'll come out on the other side with a solid application that does exactly what you want.
Let's look at the outline and then examine each step:
The purpose will answer the question, "What problem will the program solve?" It could be stated like
I need to be able to scramble the letters of my name.
or
Big Computer Corp. needs to track the sale and inventory of its products.
From these simple definitions, you can get more complex.
Big Computer Corp. needs to track the sale and inventory of its products.
Track sales figures, including quantity sold at price, quantity sold after advertising, ...
Track inventory and indicate when an item is low. ...
It's often a fine line between a purpose statement and a task statement. Often, your purpose statements will translate directly into a task statement:
Purpose: Track inventory
Function: Track inventory
The general functionality is a list of all the things you want the program to accomplish. This is from the end-user's perspective, not the programmer's. While the programmer will be concerned with how a function is accomplished, the end-user is concerned with what functions (tasks) can be accomplished. This task list should be like the marketing blurb on software packaging.
The task list for Big Computer Corp's sales and inventory system might include the following:
Are there any other tasks we might want to accomplish with this program? Yes! I forgot some important ones:
These are all tasks the program should allow the user to do. Once we have our task list created, we can go about grouping these tasks into related areas. Items in related areas will be made available to the user on separate widgets, whether they be windows or tabs or grouped items. One grouping might be like this:
Now we can start forming an idea as to how the program itself will function. The user will first see the primary tab labeled "Products." From there, other tabs are available for the other tasks.
With our task groups defined, we can start working on the PC. At this point, if I had an IDE, I could just start dropping widgets on a window and see what develops. That's a way of "sketching" on the computer, and just as valid as sketching something out on a notepad. I do like the idea of sketching on paper, however, because then you can do some design work. For instance, I can quickly sketch a few layout ideas on paper a lot faster than I could in Photoshop or an IDE.
SAMPLE HAND-DRAWN DESIGNS HERE
Here are some samples I did using Judith's Win32Lib IDE. I like the button idea better than the tabs idea, but that could change tomorrow.
For now, we're going to go with a simple design not involving the fancy elements of the hand-drawn designs.
Once I've decided on a general interface, I'll identify the components of the window that will need to move together. This means finding "frames" within which to put my user interface widgets. I'll determine that when the user resizes the window, I want certain widgets to expand, others to move, and others to stay put. Further development of the design brings us to this:
I've got two frames (as outlined by the red boxes), which I'll label "left" and "right." The left frame will hold the buttons (the buttons will be toggle buttons). This frame will not move and will resize only vertically. The right frame will hold the workspace and will not move but will expand to fit.
Now let's write some code!
Before I lay down code (which we'll do very shortly), I like to make an outline (hierarchy) of my GUI interface. I list the control's description, then the variable name I'll use for it. Here's what the outline looks like for our demo program:
I'm going to step-through coding this GUI application.
Obviously, we first need to determine what GUI package we want to use. We have many options, but I like the idea of a cross-platform library. I can code once and let Windows and Linux/FreeBSD users run the same program.
include wxEuphoria.e -- main wxEuphoria code
include wxCheckBox.e -- code for using checkboxes (including toggle buttons)
include wxSizer.e -- code needed for resizing/repositioning widgets
Then I create all the controls, in order, using my outline. I indent all child widgets to keep everything organized.
constant
win_Main = create( wxFrame, {0, -1, "Big Corp Product Manager", -1, -1, 320, 230}),
panel_left = create( wxPanel, win_Main ),
bttn_Products = create( wxToggleButton, {panel_left, -1, "Products", -1, -1, -1, -1 }),
bttn_Reports = create( wxToggleButton, {panel_left, -1, "Reports", -1, -1, -1, -1 }),
bttn_Inv = create( wxToggleButton, {panel_left, -1, "Inventory", -1, -1, -1, -1 }),
panel_right = create( wxPanel, {panel_left, -1, -1, -1, -1, -1, wxRAISED_BORDER}),
Frame_Products = create( wxPanel, {panel_right, -1, -1, -1, -1, -1, wxRAISED_BORDER}),
Frame_Reports = create( wxPanel, {panel_right, -1, -1, -1, -1, -1, wxRAISED_BORDER}),
Frame_Inv = create( wxPanel, {panel_right, -1, -1, -1, -1, -1, wxRAISED_BORDER})
Make a note that wxWidgets refers to "windows" as "frames."
Now we're going to put it all together.
procedure main()
atom vsizer, hsizer
hsizer = create( wxBoxSizer, wxHORIZONTAL )
vsizer = create( wxBoxSizer, wxVERTICAL )
add_window_to_sizer( vsizer, bttn_Products, 0, wxTOP, 0 )
add_window_to_sizer( vsizer, bttn_Reports, 0, wxTOP, 4 )
add_window_to_sizer( vsizer, bttn_Inv, 0, wxTOP, 4 )
add_sizer_to_sizer( hsizer, vsizer, 0, wxALIGN_CENTER + wxLEFT, 4 )
add_window_to_sizer( hsizer, panel_right, 1, wxGROW + wxALL, 5 )
set_sizer( panel_left, hsizer )
wxMain( win_Main )
end procedure
main()