Site Navigation
VegUIClient - Part 2 - Building the application front-end
written by vegu on 22 Jun, 2007 01:57:25
Okay, in the
first part of this tutorial series we went over the file structure of the vegUIclient addon and set it up so that we can now build our application on top of it.
First let's define what we will need in terms of widgets.
We will need a window that will perform as our text editor. The window will hold a text-area node that we will use to edit the contents of a file and a button to save the changes. Oh and of course a button to load the current file contents from the server.
For simplicity we will make it so that the window is opened automatically when the site is loaded.
For theming we will use the styles and graphics from the earlier vegUI tutorials. You can download the graphics
here.
Removing the serverinfo module
Before we get to the building part we will remove something first, though. The serverinfo module. We dont need it and it's only purpose is to serve as an example :D
Go to the ui/commented directory and open the file compile.sh (if youre on linux) or the file compile.bat (if youre on windows) and remove the "vegui.serverinfo.class.js" from it. Then run the file to recompile the vegui_client.js library.
You can also remove the vegui.serverinfo.class.js file for the sake of being tidy.
Before we proceed, just because i know some of you skipped this part in the first tutorial, make sure that youre /index.php file is including the commented library not the compressed one.
<script src="ui/compressed/vegui_client.js" type="text/javascript"></script>
needs to be change to
<script src="ui/commented/vegui_client.js" type="text/javascript"></script>
in index.php
Then open the ui/templates.js file and remove the section that sets up the template for the serverinfo display:
var o = Client.add_child('ServerInfo', VUI_SERVER_INFO);
o.set('div',0,100,100,100);
o.set_marg(100,100);
o.T.className = 'serverinfo';
Now go to the module directory and remove the serverinfo sub directory, we wont need it anymore.
Okay if you load index.php in your browser now all you should see the black manager node, no more server infos.
Creating the front-end module for our editor
Go to the ui/commented directory again and create a new file called simpleeditor.class.js. This will be the library file that contains the front-end part of our simple editor module.
When i write my modules, for what ever framework, i like to split it up into sections, a global section where i define functions and constants, and a section for the module, neatly delimited by comments.
Lets start with the global section this is were we will define a vegui element type for our module, as well as initialize our module so that the manager can later find it when it's type is submitted to one of the manager's functions.
var VUI_SIMPLE_EDITOR = 2455;
vui_module_add(VUI_SIMPLE_EDITOR, SimpleEditor, 'simpleeditor.class.js');
Now we will write the actual module, i will not go as in depth as i did with the
calculator application tutorial, so i highly recommend you read that if you haven't yet.
function SimpleEditor(refName, Parent, Manager) {
this.constructor = VegUIWindow;
this.constructor(refName, Parent, Manager);
this.type = VUI_SIMPLE_EDITOR;
this.BtnSave = this.Ui.add_child('BtnSave', VUI_BUTTON);
this.BtnLoad = this.Ui.add_child('BtnLoad', VUI_BUTTON);
this.FldText = this.Ui.add_child('FldText', VUI_NODE);
this.build = this.build_editor;
this.exec_xml = this.exec_xml_editor;
}
SimpleEditor.prototype = VegUIWindow;
Okay, we have created the constructor for the SimpleEditor object, using prototype we extended it's properties from the VegUIWindow element.
As you see we also have added three child elements to the Ui element that was taken over from VegUIWindow. Interactive elements that you add to windows or any objects extended from the window should always be added to the Ui child, not directly to the window element.
BtnLoad, is the button element that we will use to load our text file into the editor, BtnSave is the button element that we will use to save any changes we make to the text file back to server. And FldText will be a simple textarea node that we will use to display and edit the text.
We will also need to define a couple of methods in order to make our module do stuff. We add them using the prototype property of the object, because
it's the smart thing to do.
SimpleEditor.prototype.build_editor = function(toNode) {
if(!this.build_win())
return null;
var M = this.Manager;
var E = this;
this.BtnSave.States[VUI_MOUSE_UP].Scripts.add(
function() {
M.request(
'simpleedit.save', 'text='+escape(E.FldText.Base.value), 'POST'
);
}
);
this.BtnLoad.States[VUI_MOUSE_UP].Scripts.add(
function() {
M.request('simpleedit.load');
}
);
this.dock(toNode);
return 1;
};
We create the editor's own build method. Mainly to set up the mouse states of the buttons. Note that i am using the state VUI_MOUSE_UP instead of VUI_MOUSE_DOWN, because of the way the vegUI element focus is set up using VUI_MOUSE_DOWN on buttons placed in a window can mess things up.
SimpleEditor.prototype.exec_xml_editor = function(xml) {
if(!xml || !xml.length)
return 0;
var c = xml, i, e;
for(i = 0; i < c.length; i++) {
e = c[i];
if(e.nodeName == 'op') {
switch(e.getAttribute('id')) {
case 'load':
this.FldText.Base.value = e.getAttribute('text');
break;
}
}
}
};
This is the function that will handle the server responses received from a request to the server. We will use xml as a protocol so when the user clicks on the load button and the simpleedit.load script is requested from the server, the response could look something like this:
<vegui>
<module name="SimpleEditor">
<op id="load" text="The contents of the text file" />
</module>
</vegui>
I will go more in-depth on the network protocol later, but just so you understand how the front end handles the server response in case of a selected XML protocol.
The initial response will be handled by the VegUIClient object, it will see the module tag, which serves as a router and all sub elements of the module tag will be sent as an xml object to the specified module's exec_xml function.
Alright, we're done with the front-end library for now. Save the file and open up the compressed/compile.(sh/bat) and add the file to the list. If youre on a windows box and need to edit the bat file make sure to add a plus sign in front of the filename.
Save the compile script and run it to recompile the vegui_client.js library to include our module.
Now its time to set up the template and theme!
Open up ui/ui.css and remove the css class for the serverinfo module which we forgot to get rid of earlier when we removed the module, oops.
Then add these css classes. The comments should explain enough i hope.
.client {
background-color: #9da7bf;
}
.btn_close_1 { background-image: url('img/btn_close_0.gif'); }
.btn_close_2 { background-image: url('img/btn_close_1.gif'); }
.btn_minimize_1 { background-image: url('img/btn_minimize_0.gif'); }
.btn_minimize_2 { background-image: url('img/btn_minimize_1.gif'); }
.btn_maximize_1 { background-image: url('img/btn_maximize_0.gif'); }
.btn_maximize_2 { background-image: url('img/btn_maximize_1.gif'); }
.win_header {
background-color: #5c5b5b;
}
.win_caption {
color: #fff;
font: bold 10px Verdana, Arial, Helvetica;
}
.win {
background-color: #d9d9d9;
border: 1px #838383 solid;
}
.win_skin {
border: 1px #fff solid;
}
.win_shad {
border: 2px #838383 solid;
}
.btn_load_1 { background-image: url('img/btn_load_1.gif'); }
.btn_load_2 { background-image: url('img/btn_load_2.gif'); }
.btn_save_1 { background-image: url('img/btn_save_1.gif'); }
.btn_save_2 { background-image: url('img/btn_save_2.gif'); }
textarea.fldtext {
border: 1px #838383 solid;
background-color: #fff;
padding: 5px;
font: bold 10px Verdana, Arial, Helvetica;
color: #838383;
}
Save ui.css.
Also create a new directory called img as sub-directory of the ui directory (ui/img) and copy all the image files you
downloaded earlier into it.
Now open up ui/templates.js.
In the I N I T section add this to the bottom so that the shared FX object gets initialized.
While we are in the area, also replace this line:
Client.T.Css.backgroundColor = 'black';
to
Client.T.className = 'client';
Next we will add a generic window template that we will later use to clone the Simple Editor module from. You could theoretically assign all these properties directly to the Simple Editor module, but what if you would want to add another window based module to the application later.
genericWin = Client.get_new(VUI_WIN);
genericWin.set('My Window', 300, 150, 50, 50);
genericWin.Header.T.className = 'win_header';
genericWin.Caption.T.className = 'win_caption';
genericWin.T.className = 'win';
genericWin.event_add(
'onbuild', function(a) {
a[0].Manager.FX.effect_add(
a[0], new VegUIFXShadow()
);
}
);
genericWin.BtnClose.set(null,3,18,18,'btn_close_1','btn_close_2');
genericWin.BtnClose.set_marg(null,null,5);
genericWin.BtnMaximize.set(null,3,18,18,'btn_maximize_1','btn_maximize_2');
genericWin.BtnMaximize.set_marg(null,null,25);
genericWin.BtnMinimize.set(null,3,18,18,'btn_minimize_1','btn_minimize_2');
genericWin.BtnMinimize.set_marg(null,null,45);
genericWin.T.maxY = 0;
genericWin.T.maxH = 600;
genericWin.T.maxW = 800;
genericWin.T.minW = 150;
genericWin.T.minH = 100;
genericWin.Skin.T.className = 'win_skin';
genericWin.Skin.set_marg(2,2);
genericWin.Header.set(2,2);
genericWin.Header.set_marg(2);
Okay, we're done here for now, but we will be back in a bit. Save the file.
It is actually time now to add a second module, an extension to the VegUIClient object that we will use.
Create the file ui/commented/customclient.class.js.
We are going to add the Simpl Editor as a child element to our main application. However you should never edit the VegUIClient object to do so, because it will make you inflexible for VegUIClient patches.
So we are first going to create our own custom version of the client.
Open the file you just created and lets get to work. Don't worry this will be real quick and painless :).
function CustomClient(refName, Parent, Manager) {
this.constructor = VegUIClient;
this.constructor(refName, Parent, Manager);
this.SimpleEditor = this.add_child('SimpleEditor', VUI_SIMPLE_EDITOR);
}
CustomClient.prototype = VegUIClient;
You dont need to define a module type for modules that extend the VegUIManager, because those will always be instanced by using the new keyword manually and never over another manager. Unless maybe you would do a multi layered manager experiment, i will have to try that some time :D A VegUIManager inside a VegUIManager, i am not even sure what would happen :) Anyways back to the good stuff.
Okay, you know the drill, save the file. And open up the commented/compile.(bat|sh) and add this module to the list and run the script.
Then open ui/templates.js again - see i told you we would be back soon - and change this line:
var Client = new VegUIClient('Client');
to this:
var Client = new CustomClient('Client');
Alright, since we're already here lets set up our Simple Editor object as well. If there were going to be multiple SimpleEditor windows we would create a Simple Editor template that we would clone them from. But since there will only be one Simple Editor window we will just clone it from the GenericWindow and set up it's other properties and elements right away.
We do this under / after the genericWin set up we did earlier.
var o = Client.SimpleEditor;
o.clone(genericWin);
o.set('Simple Editor', 500, 350);
o.FldText.set('textarea', 100, 100, 10, 25);
o.FldText.T.className = 'fldtext';
o.FldText.set_marg(20,60);
o.BtnSave.set(10,0,74,27,'btn_save_1','btn_save_2');
o.BtnSave.set_marg(null,null,null,10);
o.BtnLoad.set(94,0,74,27,'btn_load_1','btn_load_2');
o.BtnLoad.set_marg(null,null,null,10);
Also, we want to make sure that the Simple Editor window is opened when the client has been built so scroll down to the bottom of the template.js file and find a function called "vuiclient_init()". This function is set as the onload event of the page meaning it gets called when the page has finished loading.
In it,
after the Client.build call add the following code.
Client.SimpleEditor.show();
Alright! Go check it out, navigate to the /index.php with your browser and if everything went smoothly you should be presented with a more or less tidy looking editor window with an field to edit text and two buttons to load and save.
That's the end of part 2 of this tutorial series, in the next part we will build the backend module that will handle retrieving the content of the text file from the server as well as saving any changes to it.
Related Posts
Your Comment
Comments
No comments yet.