Example 2: Multiple split views with navigation bar
This example shows how to write an application that handles two split views, each having a left and right pane, with a top level navigation pane that allows the end user to easily switch between the two split views.
main.4gl
This module implements the window creation and the parallel dialogs to control their content.
The code in the
MAIN
block creates four windows:
- The main window is the navigation window/pane, defined by the
TYPE=NAVIGATION
attribute. Only thed_navigator()
main dialog is started. - Two other windows are created for the customer list and details, in the
customers()
function. This function is called when the main dialog starts. The function checks if thew_customers
window exists and if needed, opens the split-view windows and starts the dialogs handling customer records. If windows already exists, it performs aCURRENT WINDOW IS w_customers
, to select the customer pane. - The second window showing orders and its corresponding dialog are created in
the
orders()
function, using the same programming pattern as in thecustomers()
function. - When the user selects one of the main dialog actions, it calls either the
customers()
, theorders()
, or theparams()
function, to show the corresponding pane. - The configuration pane is handled in the
params()
function, with the correspondingd_params_menu
dialog: When selected, the form is in read-only mode by default. The menu implements the "modify" action to edit the parameters. This action will create a modal dialog, that temporarily stops the parallel dialogs.
DEFINE c_arr DYNAMIC ARRAY OF RECORD
id INTEGER,
name VARCHAR(30),
address VARCHAR(100)
END RECORD,
c_curr INTEGER
DEFINE o_arr DYNAMIC ARRAY OF RECORD
id INTEGER,
info VARCHAR(100),
deliv DATE
END RECORD
DEFINE params RECORD
user_name VARCHAR(30),
auto_sync CHAR(1)
END RECORD
MAIN
CLOSE WINDOW SCREEN
OPEN WINDOW w_navigator WITH 10 ROWS, 80 COLUMNS
ATTRIBUTES(TYPE=NAVIGATOR)
START DIALOG d_navigator
WHILE fgl_eventLoop()
END WHILE
END MAIN
DIALOG d_navigator()
MENU
BEFORE MENU
CALL customers()
-- Note that action names must match the window names
ON ACTION w_customers ATTRIBUTES(TEXT="Customers",IMAGE="customers")
CALL customers()
ON ACTION w_orders ATTRIBUTES(TEXT="Orders",IMAGE="orders")
CALL orders()
ON ACTION w_params ATTRIBUTES(TEXT="Params",IMAGE="sync")
CALL params()
END MENU
END DIALOG
FUNCTION params()
IF ui.Window.forName("w_params") IS NULL THEN
OPEN WINDOW w_params WITH FORM "parameters"
LET params.user_name="Tom"
LET params.auto_sync="Y"
DISPLAY BY NAME params.*
START DIALOG d_params_menu
END IF
CURRENT WINDOW IS w_params
END FUNCTION
DIALOG d_params_menu()
MENU
ON ACTION modify ATTRIBUTES(TEXT="Modify")
CALL edit_params()
ON ACTION options ATTRIBUTES(TEXT="Options")
CALL options()
END MENU
END DIALOG
FUNCTION edit_params() -- This is a modal dialog
LET int_flag=FALSE
INPUT BY NAME params.* ATTRIBUTES(WITHOUT DEFAULTS)
IF NOT int_flag THEN
-- CALL save_params()
END IF
END FUNCTION
FUNCTION options()
MENU "Options" ATTRIBUTES(STYLE="dialog")
ON ACTION sync ATTRIBUTES(TEXT="Synchronize")
--
ON ACTION exit ATTRIBUTES(TEXT="Exit")
EXIT PROGRAM
ON ACTION cancel
EXIT MENU
END MENU
END FUNCTION
FUNCTION customers()
IF ui.Window.forName("w_customers") IS NULL THEN
CALL populate_customers()
OPEN WINDOW w_customers WITH FORM "customer_list"
ATTRIBUTES(TYPE=LEFT)
START DIALOG d_customer_list
OPEN WINDOW w_customer_detail WITH FORM "customer_detail"
ATTRIBUTES(TYPE=RIGHT)
START DIALOG d_customer_detail
END IF
CURRENT WINDOW IS w_customers
END FUNCTION
DIALOG d_customer_list()
DISPLAY ARRAY c_arr TO c_sr.*
ATTRIBUTES(ACCESSORYTYPE=DISCLOSUREINDICATOR)
BEFORE ROW
CURRENT WINDOW IS w_customer_detail
TERMINATE DIALOG d_customer_detail
LET c_curr = arr_curr()
DISPLAY BY NAME c_arr[c_curr].*
START DIALOG d_customer_detail
CURRENT WINDOW IS w_customers
END DISPLAY
END DIALOG
DIALOG d_customer_detail()
MENU
ON ACTION details
LET int_flag=FALSE
INPUT BY NAME c_arr[c_curr].name,
c_arr[c_curr].address
WITHOUT DEFAULTS
IF NOT int_flag THEN
DISPLAY BY NAME c_arr[c_curr].*
END IF
END MENU
END DIALOG
FUNCTION populate_customers()
LET c_arr[1].id = 324
LET c_arr[1].name = "Mike Treeman"
LET c_arr[1].address = "56 Gamleed st."
LET c_arr[2].id = 8934
LET c_arr[2].name = "Stepfan Plombier"
LET c_arr[2].address = "78 Pokam st."
LET c_arr[3].id = 451
LET c_arr[3].name = "Ted Barber"
LET c_arr[3].address = "1243b Western st."
END FUNCTION
FUNCTION orders()
IF ui.Window.forName("w_orders") IS NULL THEN
CALL populate_orders()
OPEN WINDOW w_orders WITH FORM "order_list"
START DIALOG d_order_list
END IF
CURRENT WINDOW IS w_orders
END FUNCTION
DIALOG d_order_list()
DISPLAY ARRAY o_arr TO o_sr.*
END DISPLAY
END DIALOG
FUNCTION populate_orders()
LET o_arr[1].id = 43249
LET o_arr[1].info = "Xmass gifts"
LET o_arr[1].deliv = MDY(12,23,2011)
LET o_arr[2].id = 33424
LET o_arr[2].info = "Dressing items"
LET o_arr[2].deliv = MDY(2,13,2012)
END FUNCTION
customer_list.per
This is the form defining the customer list, it is used for the left-pane of the
customers split view.
LAYOUT (TEXT="Customers")
TABLE
{
[c1 |c2 ]
}
END
END
ATTRIBUTES
PHANTOM FORMONLY.id;
EDIT c1=FORMONLY.name;
EDIT c2=FORMONLY.address;
END
INSTRUCTIONS
SCREEN RECORD c_sr(FORMONLY.*);
END
customer_detail.per
This is the form defining fields to show customer details, it is used for the right-pane
of the customers split view.
LAYOUT (TEXT="Customer details")
GRID
{
Id [f01 ]
Name [f02 ]
Address [f03 ]
[b1_details ]
}
END
END
ATTRIBUTES
EDIT f01=FORMONLY.id;
EDIT f02=FORMONLY.name, SCROLL;
EDIT f03=FORMONLY.address, SCROLL;
BUTTON b1_details:details,TEXT="Modify details";
END
order_list.per
This is the form defining the order list, it is a single form (not a split
view)
LAYOUT (TEXT="Orders")
TABLE
{
[c1 |c2 ]
}
END
END
ATTRIBUTES
PHANTOM FORMONLY.id;
EDIT c1=FORMONLY.info;
EDIT c2=FORMONLY.date;
END
INSTRUCTIONS
SCREEN RECORD o_sr(FORMONLY.*);
END
parameters.per
LAYOUT (TEXT="Settings")
GRID
{
User [f01 ]
Auto sync [f02 ]
}
END
END
ATTRIBUTES
EDIT f01=FORMONLY.user_name, SCROLL;
CHECKBOX f02=FORMONLY.auto_sync, NOT NULL,
VALUECHECKED="Y", VALUEUNCHECKED="N";
END