Quantcast
Channel: Jeez Tech » Javascript
Viewing all articles
Browse latest Browse all 10

YUI Mac Like Style Desktop

$
0
0

finalized

When i first saw jQuery desktop i was amazed of what jQuery can do. I decided to "fork" the idea to YUI and check if it was possible. It took me 2 days to built it from scratch well not actually, because most of the functionality was taken from the YUI library examples. For example the panels, dialogs and menus are all taken from the examples provided with the full YUI library, but i think i did some work myself. So here it is: finalized

Applications Bar

First of all, i wanted the flowing application's bar on the bottom of the desktop (i like Mac screens but i don't own one. So if you think the desktop sucks at emulating a Mac desktop... Then you are right :) ) . So i used the sticky footer code from http://www.cssstickyfooter.com/ to place the applications bar where i wanted. Then i needed to add the icons with an effect that would make them feel like flowing (i like calling this liquid). What i did was the same trick as the YUIBox image gallery, only slightly customized. I added a mouseover listener to all images with class name = link, and a mouseout listener too. So the mouseover event to animate the resizing of the images with an easing effect and the mouseout event to restore the images original size. This is the code: [code lang="javascript"]window.onload=function() { YAHOO.namespace("example.container"); //menu(); YAHOO.example.container.manager = new YAHOO.widget.OverlayManager(); var as = document.getElementsByTagName("img"); for(var i=0; i<as.length; i++) { var a = as[i]; if(a.className.indexOf("link")>=0){ YAHOO.util.Event.addListener(a.id, "mouseover", setupAnim); YAHOO.util.Event.addListener(a.id, "mouseout", unsetupAnim); } } } var setupAnim = function(e){ var move = new YAHOO.util.Anim(e.target.id, { height: { to: 64 }, width: { to: 64 } },0.3,YAHOO.util.Easing.easeBoth); move.animate(); } var unsetupAnim = function(e){ var unmove = new YAHOO.util.Anim(e.target.id, { height: { to: 36 }, width: { to: 36 } , }, 1,YAHOO.util.Easing.easeOut); unmove.animate(); }[/code] The code above creates a cool effect. The images seem like flowing (a little buggy though. Tell me if you find it and please provide a solution too!!!) and our applications bar is almost ready. The next step was to give a depth to the applications bar. What i did was to create a simple image like this: bg this image will act as a "table" where our icons will stand on. The icons i used was taken from the crystal project package for KDE. So, i set this image as a background image for the footer of the desktop and it then looked like this: bar

The Top Menu

The top menu was easy to create. The YUI examples had one ready so, i used this. The JS code needed is: [code lang="javascript"]YAHOO.util.Event.onContentReady("topmenu", function () { /* Instantiate a MenuBar:  The first argument passed to the constructor is the id for the Menu element to be created, the second is an object literal of configuration properties. */ var oMenuBar = new YAHOO.widget.MenuBar("topmenu", { autosubmenudisplay: true, hidedelay: 750, lazyload: true }); /* Define an array of object literals, each containing the data necessary to create a submenu. */ var aSubmenuData = [ { id: "file", itemdata: [ { text: "New", submenu: { id: "new", itemdata: [ { text: "File", onclick:{ fn: newfile } }, { text: "Application", url:"#" }, { text: "Shortcut",  url: "#" }, { text: "Desktop", url: "#" } ] } }, { text: "Open", onclick:{ fn : openfile } }, { text: "Save", url: "#" }, { text: "Save as...", url: "#" }, { text: "Exit", url: "#" } ] }, { id: "edit", itemdata: [ { text: "Undo", url: "#" }, { text: "Copy", url: "#" }, { text: "Paste", url: "#" }, { text: "Select All", url: "#" } ] }, { id: "view", itemdata: [ { text: "HTML Source", url: "view-source:"+document.location }, { text: "Javascript Source", url: "view-source:"+document.location+"k800.js" }, { text: "CSS Source", url: "view-source:"+document.location+"css/style.css" } ] }, { id: "go", itemdata: [ { text: "Google", url: "http://www.google.com" }, { text: "Yahoo!", url: "http://www.yahoo.com" }, { text: "Jeez Tech", url: "http://jeez.eu" }, { text: "Reddit", url: "http://reddit.com" } ] } ]; /* Subscribe to the "beforerender" event, adding a submenu to each of the items in the MenuBar instance. */ oMenuBar.subscribe("beforeRender", function () { var nSubmenus = aSubmenuData.length, i; if (this.getRoot() == this) { for (i = 0; i < nSubmenus; i++) { this.getItem(i).cfg.setProperty("submenu", aSubmenuData[i]); } } }); /* Call the "render" method with no arguments since the markup for this MenuBar instance is already exists in the page. */ oMenuBar.render(); });[/code] and the html code is: [code lang="html"]<div id="doc"> <div id="hd"> <!-- start: your content here --> <!-- end: your content here --> </div> <div id="bd"> <!-- start: primary column from outer template --> <div id="yui-main"> <div> <!-- start: stack grids here --> <div id="topmenu"> <div> <ul> <li> <a href="#">File</a> </li> <li> <a href="#">Edit</a> </li> <li> <a href="#">View</a> </li> <li> <a href="#">Go</a> </li> </ul> </div> </div> </div> </div> <!-- end: primary column from outer template --> <!-- start: secondary column from outer template --> <div> </div> <!-- end: secondary column from outer template --> </div> <div id="ft"> </div> </div>[/code] Now, the desktop had an applications bar and a top menu. The next thing to do was to add some functionality.

Functionality

What i wanted to do was to allow the icons on the applications bar to be able of opening some windows, a context menu and some top menu functionality like:
  • Display a text editor when we click on the New -> File item, and
  • display an Open File dialog when we click on the Open File item.
Open windows from application icons windows This was easier than i thought. I just added an event listener on the click event for all icons and a function to create a window for each one of them, based on their id and title. I also wanted to handle focus on every window, so i registered each panel in a container manager. Another thing i wanted the windows was to be resizable, draggable and the ability to maximize and minimize them. The code needed (needs some refactoring too): [code lang="javascript"]var openPanel = function(e){ var pano = new YAHOO.widget.Panel("pano"+e.target.id, { xy:[250*(e.target.id/3),100*(e.target.id/3)], width:"600px", height:"300px", visible:false, draggable:false, close:true} ); pano.setHeader(e.target.title+"<span id='max' class='container-max'></span><span id='min' class='container-min'></span>"); pano.setBody("You clicked on the "+e.target.src+" image with id "+e.target.id+""); pano.setFooter("End of Panel #"+e.target.id); pano.render("wrap"); pano.cfg.setProperty("draggable",true); var resize = new YAHOO.util.Resize("pano"+e.target.id, { handles: ['br'], autoRatio: true, minWidth: 300, minHeight: 100, status: false, proxy: true }); resize.on("resize", function(args) { var D = YAHOO.util.Dom; var clientRegion = D.getClientRegion(); var elRegion = D.getRegion(this.element); resize.set("maxWidth", clientRegion.right - elRegion.left - YAHOO.widget.Overlay.VIEWPORT_OFFSET); resize.set("maxHeight", clientRegion.bottom - elRegion.top - YAHOO.widget.Overlay.VIEWPORT_OFFSET); pano.cfg.setProperty("height",args.panelHeight+"px"); }, pano, true); YAHOO.example.container.manager.register([pano]); pano.show(); YAHOO.util.Event.addListener('max', "click", function(e){ pano.cfg.setProperty('width',screen.width+100); pano.cfg.setProperty('height',YAHOO.util.Dom.getViewportHeight()-30); },pano,true); YAHOO.util.Event.addListener('min', "click", function(e){ pano.cfg.setProperty('width',600); pano.cfg.setProperty('height',300); },pano,true); }[/code] Create new file editor This one was a little tricky. I had to set the focusAtStart: true property uppon creation of the editor in order to make the editor usable in the dialog. The code used is: [code lang="javascript"]function newfile(){ if(document.getElementById('dialogContainer')){ dlg.destroy(); } var results = document.getElementById('menuresult'); var newdiv = document.createElement('div'); newdiv.setAttribute('id', 'dialogContainer'); newdiv.innerHTML = "<div class='hd'>Enter Title and Contents:</div><div class='bd'><form id='dialogForm' name='dialogForm' method='post' action='#'><p><label for='title'>Title:</label> <input name='title' id='title' /></p><p><label for='description'>Contents:</label></p><textarea name='editor' id='editor'></textarea><div id='descriptionContainer'></div></form></div>"; results.appendChild(newdiv); //create the RTE: var editor = new YAHOO.widget.Editor('editor', { width: '702px', height: '200px', focusAtStart: true }); //After the Editor renders it, we will hide it //so the iframe doesn't bleed through //editor.on('afterRender', editor.hide); //render the editor explicitly into a container //within the Dialog's DOM: editor.render(); //create Dialog: var dlg = new YAHOO.widget.Dialog("dialogContainer", { width:"725px", fixedcenter:false, modal:false, close:false, visible:false }); //event handlers for our Dialog buttons: //if the user clicks "save", then we save the HTML //content of the RTE and submit the dialog: function handleSave() { alert("You pressed on Save"); } //if the user clicks cancel, we call Dialog's //cancel method: function handleCancel() { this.destroy(); } //set up buttons for the Dialog and wire them //up to our handlers: var myButtons = [ { text:"Save", handler:handleSave }, { text:"Cancel", handler:handleCancel, isDefault:true } ]; dlg.cfg.queueProperty("buttons", myButtons); var onSuccess = function(o) { } var onFailure = function(o) { } dlg.callback.success = onSuccess; dlg.callback.failure = onFailure; //Now that our Dialog is fully configured, we can //render it: dlg.render(); dlg.showEvent.subscribe(editor.show, editor, true); dlg.hideEvent.subscribe(editor.hide, editor, true); //instantiate button to show Dialog: // dlg.show(); }[/code] Open file dialog open The same logic as the "create new file" method used: [code lang="javascript"]function openfile(){ if(document.getElementById('dialogContainer')){ dlg.destroy(); } var results = document.getElementById('menuresult'); var newdiv = document.createElement('div'); newdiv.setAttribute('id', 'dialogContainer'); newdiv.innerHTML = "<div class='hd'>Open File...</div><div class='bd'><input type='file'></div>"; results.appendChild(newdiv); var handleYes = function() { alert("Opening file..."); this.destroy(); }; var handleNo = function() { this.destroy(); }; var dlg1 = new YAHOO.widget.Dialog("dialogContainer", { width: "300px", fixedcenter: true, visible: false, draggable: true, icon: YAHOO.widget.SimpleDialog.ICON_HELP, close: false, constraintoviewport: true, buttons: [ { text:"Open File", handler:handleYes, isDefault:true }, { text:"Cancel",  handler:handleNo } ] } ); // Render the Dialog dlg1.render(results); dlg1.show(); }[/code] Context Menu This was the easiest of all. The code needed is: [code lang="javascript"]var oFieldContextMenuItemData = [ { text: "Visit Jeez Tech", url: "http://jeez.eu" }, { text: "About", onclick: { fn: about } } ]; /* Instantiate a ContextMenu:  The first argument passed to the constructor is the id for the Menu element to be created, the second is an object literal of configuration properties. */ var oFieldContextMenu = new YAHOO.widget.ContextMenu( "fieldcontextmenu", { trigger: "wrap", itemdata: oFieldContextMenuItemData, lazyload: true } );[/code]

Demo and Download

You can view a live demo or download the desktop.

Viewing all articles
Browse latest Browse all 10

Trending Articles