Providing affordable quality software that increases productivity
D/DWT Tutorial 3: Adding a button
Let's add a button to our application and use it to exit the application. We will add an event listener and add some functionality to our application framework.
We start with our application template and add the code to create a button in the function
createGUIControls()
Add the correct imports to the top of the file:
import dwt.widgets.Button; import dwt.widgets.Event; import dwt.widgets.Listener; import dwt.graphics.Image;
Add the button declaration to the class:
public class MainForm : Shell
{
private:
Button btnClose;
//.... Code removed for readability
void createGUIControls()
{
// Add a push button the MainForm (this)
btnClose = new Button(this,DWT.PUSH);
btnClose.setBounds(10,10,100,25);
btnClose.setText("Close");
// Add a listener to the Button.
btnClose.addListener(DWT.Selection,new class Listener {
void handleEvent(Event event)
{
this.outer.close();
}
} );
}
}
If you take a close look a btnClose.addListener line you'll see that a new class is created that implements a function
void handleEvent(Event)
To respond to events from the button we have to implement a listener class. This means that we would have to create a new object for each button, or, if we use one object, we somehow would have to catch all the events and find out which button generated the event. That's a lot of work when all we really want is to specify a method that responds to the event.
Luckily D has the concept of delegates. Let's build a helper class that accepts a method.
// event listener helper class
// This class wraps a delegate inside a generic DWT event listener
class DelegateListener : Listener
{
// cb holds the delegate function.
private void delegate(Event event) cb;
// constructor. Pass the method that you want to call when the event occurs
this(void delegate(Event event) callback)
{
cb = callback;
}
// called by the generator of the event.
void handleEvent(Event event)
{
cb(event);
}
}
When we use this class we can pass a method to the button to respond to events.
public class MainForm : Shell
{
// ... Code removed for readability
void createGUIControls()
{
// Add a push button the MainForm (this)
btnClose = new Button(this,DWT.PUSH);
btnClose.setText("Close");
// Add a listener to the Button.
btnClose.addListener(DWT.Selection,new DelegateListener(&onCloseClick));
}
// Method to respond to button clicks:
void onCloseClick(Event e)
{
// close the Window.
close();
}
}
That completes our application with a button. We will add the DelegateListener to our application template.
D/DWT Tutorial 2: Standard app framework 1
When writing software we should structure our code in a logical way and separate functions into different classes and modules. We do this because it makes code easier to maintain.
We will create a template structure which we will use as the basis for all our applications.
So instead of creating a Shell directly, we will create a shell subclass which is our main application form. We will use certain conventions such as function names. You are free to choose your own.
import dwt.DWT;
import dwt.widgets.Display;
import dwt.widgets.Shell;
import dwt.graphics.Image;
// This is our mainform.
// It inherits from Shell and sets up all necessary controls and
// it responds to interface events like mouse clicks and keyboard input.
public class MainForm : Shell
{
public:
this(Display dpy)
{
// call the constructor of Shell explicitly
super(dpy);
// Set the size of the window to 800x600
setSize(800,600);
// Set its name to "Demo app 2"
setText("Demo app 2");
// Set the icon of the application to app.png (must be in the same directory as the executable
setImage(new Image(getDisplay(),"app.png"));
// Setup all the controls such as the menu bar, buttons etc..
createGUIControls();
private:
void createGUIControls()
{
// Create all controls that make up the interface.
}
}
void main()
{
Display dpy = new Display();
// Instead of creating a shell, we create our own mainform (which inherits from Shell)
MainForm frmMain = new MainForm(dpy);
frmMain.open();
// Main event loop.
// Keep running until closed
while (!frmMain.isDisposed())
{
// fetch events from the queue and send to the app.
if (!dpy.readAndDispatch())
dpy.sleep();
}
// release resources
dpy.dispose();
}
D/SWT programming tutorial
We are building our applications in D and DWT. D has a strong user base but documentation seems to be scarce. So we decided to write our own D/DWT tutorial. Today the introduction.
Writing an application in D and DWT means using Tango. There are DWT/Phobos implementations out there but I don't recommend it. Tango is a good, strong programming library that has more features than Phobos.
So here we go: Opening a Window
import dwt.DWT;
import dwt.widgets.Display;
import dwt.widgets.Shell;
void main()
{
// new Display is the output device for the application.
Display dpy = new Display();
// Windows are called Shells. You can open as many shells as you want.
// Shells that have Display as their parent are "top level" shells and
// will have a related button in the taskbar. Child shells have a shell
// as their parent and don't have a button in the taskbar
// Shells can contain controls because the shell is a composite.
Shell frmMain = new Shell(dpy);
frmMain.open();
// Main event loop.
// Keep running until closed
while (!frmMain.isDisposed())
{
// fetch events from the queue and send to the app.
if (!dpy.readAndDispatch())
dpy.sleep();
}
// Release resources
dpy.dispose();
}
Task Manager Delay
We've been working really hard on Task Manager but we had some unfortune set backs. Rather than deliver a half baked product now, we at proficio software believe that it's better to deliver a good product a little bit later.
This means that we will have to delay Task Manager by a couple of weeks.
Please check back in a little while. It will be available for download soon.
SQLite bindings for D
For our TaskManager project we needed a storage backend and SQLite is a solid and popular database engine. It stores the database in a plain file and the database can be embedded into the application. No need to install anything. It's so good that Apple decided to included it in their operating system.
Since we are writing our application in D we needed D bindings; but alas, the only bindings on the net were old 3.0.0 bindings. So we decided to port it ourself.
Download SQLite 3.5.16 bindings for D:
Without SQLite sources:
* as a zip file
* as a tarball
Task Manager
We've been working on a new application called Task Manager. It's actually more a todo list manager. We needed a simple fast way to enter todo items and to allocate those tasks for the day.
These were the requirements we came up with for the design.
Taskmanager has to:
- Allow users to enter todo-lists in a simple way
- Show todo tasks for Today, Tomorrow, Friday, Later
- Allow the user to drag and drop tasks to new days (i.e. move deadline)
- Provide allocation for task items into slots on a day-to-day basis, using drag and drop
- Be faster and more friendly than outlook tasks
- Allow outlook items to be dropped as new task items
Image the workflow for using the product, it matches a natural, efficient and effective working style. For references see: To-do List in Dynamic Time Management and
14 Tips to successfully manage your time
- Get to work, start up computer and start task manager
- Set your task items, move missed task items from yesterday
- Drag and drop task items into slots for the day
- Start working on items
- Mark them complete as you go
- Delete item when done
Currently TaskManager is in alpha phase and the beta version is scheduled for release at the end of June. If you are interested in testing this product drop us an email: info at proficiosoftware . com. We still need 5 more beta testers!
New product Window Move released
Window Move ScreenshotWelcome to Proficio Software.
We have just completed our new product Window Move.
This product is the perfect solution when you need to move a window when its title bar is off screen. If you work with multiple displays and you find that you can't see a window, but it's sitting in the task bar, chances are that it's off screen because when switching monitors the external monitor was on the left instead of right hand side.
