GUI interface
From FreemedDeveloperWiki, the FreeMED developers' Wiki.
The GUI interface is designed to provide small, simple cross-platform applications, made with reusable components, to speed up tasks that are unwieldy with the web interface.
The interface is designed with wxPerl, using wxGlade for the layout. Components live in the FreeMED::UI namespace; for instance, the login dialog is FreeMED::UI::LoginDialog. To interface with a FreeMED installation, an XMLRPC library is called via components in FreeMED::XMLRPC.
Contents |
Design goals
- Use reusable and well-defined components to allow for the easy building of custom applications.
- Mirror the web interface where it is possible and sensible to do so.
- Increase responsiveness by using a more network-light method of interaction with the server.
Conventions
Class members
Data inside a class is referred to as $self->{something}. Uppercase names are only used for standard, defined values, such as ->{SUMMARY} and ->{RECORD} as shown below.
Selection dialogs
Selection dialogs (such as FreeMED::UI::PhysicianSelect) shall provide the functions GetRecord and GetSummary. GetRecord will return a hash reference to the entire record (including the id field); GetSummary will return a scalar containing a human-readable summary suitable for inclusion in a list or on a button. Internally, these values are stored as $self->{SUMMARY} and $self->{RECORD} so that the functions can always be coded as follows.
sub GetSummary {
my ($self) = @_;
return $self->{SUMMARY};
}
sub GetRecord {
my ($self) = @_;
return $self->{RECORD};
}
If the data is being pulled from a Wx::ListBox, the ListBox should be called $self->{RESULTS}. In this case, the implementation may look more like the following.
sub GetSummary {
my ($self) = @_;
return $self->{RESULTS}->GetStringSelection;
}
sub GetRecord {
my ($self) = @_;
return $self->{RESULTS}->GetClientData($self->{results}->GetSelection);
}
This convention (GetSummary/GetRecord) goes for other derived classes---custom buttons, for instance---as well.
Conversion progress
Current status of conversion to the above convention. Dialogs like StockDrugs don't need to follow it, because they don't return any data; they perform an action on it themselves.
| Not done | Done | Not applicable |
|---|---|---|
| PatientSelection | SelectButton PhysicianSelect DrugSelect | DispenseStockDrugs StockDrugs LoginDialog |
Caveats
- As of wxGlade 0.3.5.1, code generation only works in the single-file mode. There's a script to split up the generated program (split.pl), but the results require tweaking.
- As of wxGlade 0.3.5.1, wxGlade will report success for code generation even if the output file exists and its configuration prevents it from overwriting it.
- If the main window has closed, but the application is still running, it's most probable that you've forgotten to destroy a dialog box. A function that calls a modal dialog should dispose of it whether or not its actions are cancelled.
sub ImportantEventHandler {
my ($this, $event) = @_;
my $dlg = FreeMED::UI::SpiffyDialog->new;
my $ret = $dlg->ShowModal;
if ($ret == wxCANCEL) { $dlg->Destroy; $event->Skip; return; }
# the GetClientData method doesn't exist for dialogs, but it's useful, so we create it
my $data = $dlg->GetClientData;
$dlg->Destroy; $event->Skip;
return $data;
}
Todo
- add (more) code examples
- add screenshots
- describe the structure of most of these applications, how to put one together.