Mocha UI is a MooTools user interface class made with canvas tag graphics. This is an on going exercise to help me become more familiar with both MooTools and the canvas tag.

Features

Demo and Download

  • No images. The windows, including their controls, gradients and shadows, are drawn with the canvas tag.
  • Adjustable rounded corner radius.
  • Windows can be focused, dragged, resized, maximized, restored down and closed.
  • Dynamically create new windows on demand.
  • Fullwindow window size is adjusted if the browser window size changes.
  • Minimal HTML markup required.
  • Tested in Firefox 2, Internet Explorer 6 & 7, Safari 2, and Opera 9.

39 Responses

  1. #1
    qureyoon

    brilliant ! awesome job here ^^
    thanks for sharing :D

  2. #2
    Jumbooze

    Looks great, I usually use http://prototype-window.xilinus.com/themes.html.
    I use a lot of modal windows and on close triggers.
    Would be nice to see that in your Mocha.

  3. #3
    kow

    Hi,

    I also used PWC here: www.universite.hu, but if I had found yours earlier, I’d definetly use Mocha.

    Cheers,
    Power it up, It worths an 1.0 state.

  4. #4
    Dave

    Pretty cool!
    I wonder: How does Canvas perform besides standard JS border and drop shadow ‘rendering’ etc?

    If good, this would be a nice addition to the gazillion rounded-borders-through-js scripts: less markup clutter (although generated by JS) etc…

  5. #5
    Al

    Hi Greg

    Really like Mocha, fantastic window implementation!

    I have had a little play around with it and found it easy to use.

    One issue I had was trying to put an iframe inside one of the mocha windows and could get the width to 100% but not the height using Firefox on the mac, safari was fine. Also couldn’t seem to loose some of the padding/margin to take the iframe to the edges.

    If you get a mo can you take a look as this would be great with good iframe support.

    regards
    Al

  6. #6
    Marcio

    It’s possible use

    prototype.js

    scriptaculous.js

    With

    mocha.js

    ?

    Because this error ocurred

    $(”#mochaDesktop div.mocha”) has no properties
    scripts/mocha_v0.5/scripts/mocha.js
    Line 39

  7. #7
    susi

    what i’ve seen is… wonderful!!!

    i have a little question:
    my skills about javascript are… well, i’m a newbie… is it possible to open a window from a linkand how?

    thanks for your development!

  8. #8
    Greg Houston

    Marcio, unfortunately the MooTools and Prototype frameworks are not compatible. It’s suggested that you use one or the other.

  9. #9
    Marcio

    Thanks for answering friend

    Frankly your script is fantastic my congratulations and that the God bless

  10. #10
    Hostile Fork

    This is very pretty… one of the nicest looks I’ve seen in web desktops. Interesting that you don’t use images to do it.

    I was looking at a similar package (extjs) and hit the Firefox Z-order bug on mac too. Thought you or your visitors might be interested in the workaround I pieced together here:

    http://hostilefork.com/2007/11/06/workaround-firefox-scrollbar-bug-on-mac/

    Best wishes,
    HF

  11. #11
    Neven

    Hi there :) Great stuff, I only have one question :)
    Is it possible to limit the width of a container so that the window that dont fit in the specified width goes down under the first window, like a classic 2 or 3 column layout.

    When i limit the “setDesktopSize: function()” width of a mochaDesktop windows are still going off screen.

    Tnx in advance.

  12. #12
    Greg Houston

    Hi Neven. I didn’t quite follow your question.

    setDesktopSize sets the desktop area to the available width and height of your browser window. It doesn’t control the width of the windows at all. You set the initial width of each window in the html. You can also try setting desktopLeftOffset and mochaLeftOffset in the options to lower numbers. When the windows first appear they will be closer to the left side of the browser window then.

    If you understand javascript logic and how to code it you can make the windows display initially wherever you want them to by modifying the displayAll method. Right now each window is just placed a little further right, and a little further down than the previous one. Unfortunately I don’t have the time to personally modify this code for individual projects. :(

    Good luck.

  13. #13
    Neven

    @Greg

    The displayAll did the trick:) I positioned every window where I wanted it, I am just lookin for a better solution.

    Lets say the user resolution is 1024 width, and we put 3 window each 400px width, horizontal scroller is then active, that is the issue.

    here is the demo

    I was wondering is there a way to set max width so that the 4th and 5th window goes below 1st and 2nd.

    I understand the time issue, so dont worry I dont expect you to give anyone a complete solution but since you are the author of mocha, a hint would be just fine :) tnx for the reply.

  14. #14
    Greg Houston

    Neven, I like your yellow gradient headers. :)

    So before you proceed you probably want to revert the setDesktopSize method to what it was before you started experimenting. That is probably what is throwing off your maximize action.

    You have to approach this like a logic puzzle. To do that you need to know what you can work with. In this case you can test for the width of the browser, you can test for the top left corner of each UI window, and since you can test for the width and height of each UI window you can test for all the other corners of each UI window.

    So in your displayAll method then you can make it so each window successively appears 20px to the right of the previous window unless the current UI window’s right corner (its left position plus width) has a position greater than the browser width. If the UI window’s right corner position is greater than the width of the user’s browser then you simply set its left to 0 again, and increase it’s top by the height of the tallest window to precede it plus 20px or so.

    This is conditional logic. Once you understand how to think this way you can program just about anything you want. Know very clearly what you want to do, and think of it in precise conditional terms. As you formulate the conditionals in your head you will determine what measurements you need to know and what variables you are going to need to set along the way so you can remember what has happened in previous iterations. Then find out how to get the measurements you need. Finally turn those conditionals in your head into actual code.

    It might help if you write your conditionals out in regular words first and then gradually replace those words with code.

    If this UI window’s left position plus it’s width is greater than the browser window’s width then reset this UI window’s left position to 20 pixels and make its top position 20 pixels greater than the top position plus height of any UI window that preceeded it.

    Again, this is the foundation of programming. Once you understand this then you can read other people’s code like it were a book. You will be able to follow what is going on, and then modify it to your heart’s content.

  15. #15
    bax

    Weird Usability bug in Firefox 2.0.0.10 - the windows appear on top of the browser window’s scroll bars.

  16. #16
    paperogiallo

    Hi Greg, I really appreciate your script, and I’m wondering if is there a way to use it with current stable release of Mootools (1.11) or, even better, with the patched version of Mootools used on cnet.
    I’ve tried to do this commenting all instances of MochaMorph/Fx.Morph in mocha.js, but naturally I lost the feature to arrange and (mostly important) to maximize/minimize the “windows”.
    Since I’ve got no error using Mocha with Mootools 1.11, is there a way I can keep max/minimize feature using something different from Morph?

    Thanks again for your work, and for shared it!

    paperogiallo (in english, yellowduck)

  17. #17
    paperogiallo

    I’ve found a solution, using Fx.Styles instead of Fx.Morph, and everything works well, except for one thing: the maximize button.
    If I use Fx.Styles, leaving all other code untouched, first time the script run, el.retoreMaxToggle is set to ‘restore’ instead of ‘maximize’, and I can’t figure out why. As a result, the first click on maximize (+) button throws an error, while clicking double maximizes the MochaWindow.
    All I’ve done is to change ‘var mochaMorph = new Fx.Morph(el …)’ with ‘var mochaMorph = new Fx.Styles(el …)’ four times in your code.

  18. #18
    Greg Houston

    Paperogiallo, I don’t know if it will solve your issue, but there was a typo in the last release.

    retoreMaxToggle should be restoreMaxToggle.

    It is fixed in the next version yet to be released.

    Beyond that I don’t know that I can be much help. I haven’t worked with Mootools 1.11 at all. I started with 1.2 dev and am now using the backwards compatible 1.2 beta.

    Good luck.

  19. #19
    paperogiallo

    Well, if 1.2 beta is (I hope, completely) backwards compatible, I think I’m going to switch forward to it ;)

    Thanks for all, Greg.

  20. #20
    komakino

    Hi Greg!
    I really love this!

    A couple of questions:

    1: How do i close a window from a link?

    2: Is there now OnClose option for windows?

    /komakino

  21. #21
    Greg Houston

    Komakino, glad you like it.

    To close a window from a link you should probably create a function for it, and call the function from the link. If you really wanted to do it right you could add an event listener to the link rather than using an inline event.

    But here is the quick and dirty way to close a window from a link:


    <a href="" onclick="javascript:if($('myDivID')){$('myDivID').remove();}return false;">Remove Window</a>

    Replace myDivID with the id property of the window you wish to remove.

    The conditional makes sure you don’t try to close a window that doesn’t exist which would cause the entire page to refresh.

    You can also use .dispose() instead of .remove(), they do the same thing.

    There is no onClose option for the windows yet, but I will make a ticket for it.

  22. #22
    Greg Houston

    @Al. I just released Mocha UI version 0.7 and it has more iframe support, though for Firefox you will still need to set the height of your iframe to the same height as your window. I am thinking about adding a feature that resizes the iframe to the same dimensions of the window, but that would be in yet a later release.

    @Susi. The latest version of Mochu UI has support for creating a new window from a link.

  23. #23
    komakino

    Hi Again!

    Thanks for the reply! It sounds great.

    It would be really great if you could add evalScripts for ajax loaded windows, in the next release. I REALLY nead that!

    When is the next release coming? I know you released like yesterday, but i cant wait to see where this is going ;)

    Great work.

  24. #24
    captFuture

    Hi Greg,
    First of all I want to tell you that you did an awesome piece of javascript :-)

    When I first tried 0.7 on my page i came across some issues. When you just want to use the window functionality on the page you can’t delete the standard

  25. #25
    Greg Houston

    @Komakino: I haven’t used evalScripts yet and am not familiar with it’s use, but if you can make me a simple ajax demo that loads a test message into a div container and uses evalScripts I will see if I can’t implement it into Mocha.

    Cheers.

  26. #26
    Greg Houston

    @captFuture. Sorry about that. Fixing this will be on my todo list today. I will also add a second index page and name it something like clean_slate.html. That file will have the minimal html markup necessary for Mocha UI to work so people won’t have to guess what they can delete and what not.

    This will be fixed in the next release and much sooner in the svn repository.

  27. #27
    Greg Houston

    I thought I would let everyone know what we are currently working on.

    Coming in the next update to v0.7:

    • Iframes now resize when you resize a window
    • Fixed it so that if the desktop toolbars are removed the rest of the code still works
    • Removed the inline javascript from the example html
    • Added optional autohide to the dock (Scott F. Frederick)
    • Added the following options to new windows: onContentLoaded, onClose, onMinimize, onMaximize, onFocus, and onResize
    • Pulled the slider function out of the core class
    • Added more examples
  28. #28
    Phil Crosby

    The workaround to prevent the scrollbar from poking through on mac is setting overflow:auto. I used the workaround extensively on jjot.com

    This looks great. Have you thought about splitting off the rounded corners/drop shadows into a separate mootools plugin, so it could be used to decorate a web page instead of requiring the entire UI to be mocha based? I find js rounded corner/drop shadow solutions very nice for doing mocks, because I don’t want to mess around with image at that point. But it would be nice to roll something more robust (like this) into production as well.

    Greg, I wouldn’t mind helping in this effort if you’re interested.

  29. #29
    Greg Houston

    Mocha UI beta v0.7 r22 is now available.

    Demo

    Download

    Changes:

    • Iframes now resize when you resize a window
    • Fixed it so that if the desktop toolbars are removed the rest of the code still works
    • Modal windows can now be used standalone without any Mocha UI html markup
    • Removed the inline javascript from the example html
    • Added optional autohide to the dock (Scott F. Frederick)
    • Added the following options to new windows: onContentLoaded, onFocus, onResize, onMinimize, onMaximize, onClose and onCloseComplete (Joel Lindau)
    • Added screens/workspaces (Joel Lindau)
    • Pulled the slider function out of the core class
    • Code optimizations
  30. #30
    Greg Houston

    Hi Phil. I hadn’t considered making the rounded corners and drop shadows a stand alone plugin yet. Currently I am starting to think about how to make Mocha UI more modular from the get go so it is easier for people to just use the aspects they are looking for and easily remove the classes, plugins, or modules they don’t need. However my learning curve so far ends where things such as the following start … prototypes, the factory pattern, mootools implement and extend, and modules and plugins in general.

    I think the first thing I need to do is come up with basic definitions for plugins and modules, and some use scenarios for both, and then try to find the best way to implement them in Mocha UI.

    So it might be that the rounded corners and drop shadows get pulled out into their own thing, I’m just not sure yet how to get everything working together again once I start pulling it apart.

  31. #31
    komakino

    Hi again Greg!

    I need to be able to evaluate scripts loaded with ajax. In 0.7, it was an easy fix just adding “evalScript: true” to the Ajax call in mocha.js. In 0.7r22 however, you have changed to the Request method. Could you implement this or at least tell me how i can fix this for myself?

  32. #32
    komakino

    Nevermind.
    onContentLoaded kinda keeps me covered ;)

  33. #33
    Cristian

    Hi, i would like to add a new function that allows printing the contents of a window only if this onfocus from a bar menu item, i tried this:

    Inside of MochaDesktop.

    this.attachMinimize($$(’div.mocha’));
    this.attachMaximize($$(’div.mocha’));
    this.attachClose($$(’div.mocha’));
    this.printSpecial(id_focus); // New Print
    this.arrangeCascade();

    After the end of the class i added Method print, this function prints a page without headers and foot, but only work in loadMethod iframe i need your help for this work in loadMethod xhr and html

    /* Method Print */
    printSpecial: function(id_focus){

    if(id_focus !=”"){

    var gAutoPrint = true;
    var nombreIframe = id_focus + ‘Iframe’;

    if (parent.frames[nombreIframe].document.getElementById != null){
    var html = ‘\n\nPrint prewiev’;

    if (parent.frames[nombreIframe].document.getElementsByTagName != null){
    var headTags = parent.frames[nombreIframe].document.getElementsByTagName(”head”);
    if (headTags.length > 0 && headTags.name != “script”)
    html += headTags[0].innerHTML;
    }

    html += ‘\n\n\n’;

    var nombreID = “PRINT”+id_focus;
    var printReadyElem = parent.frames[nombreIframe].document.getElementById(nombreID);

    if (printReadyElem != null){
    html += printReadyElem.innerHTML;
    }else{
    alert(”This page don’t printable”);
    return;
    }

    html += ‘\n\n’;

    var width=”800″, height=”550″;
    var left = (screen.width/2) - width/2;
    var top = (screen.height/2) - height/2;
    var styleStr = ‘toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=yes,copyhistory=yes,width=’+width+’,height=’+height+’,left=’+left+’,top=’+top+’,screenX=’+left+’,screenY=’+top;
    printWin = window.open(”",”printSpecial”+id_focus, styleStr);
    printWin.document.open();
    printWin.document.write(html);
    printWin.document.close();
    if (gAutoPrint) printWin.print();

    }else{
    alert(”Update your broswer”);
    }
    printWin.window.close();
    }
    }
    });
    MochaDesktop.implement(new Options);

    /* the menu items fuction is printLink, the page for to print is AnyPageLink */

    if ($(’AnyPageLink’)){
    $(’AnyPageLink’).addEvent(’click’, function(e){
    new Event(e).stop();
    document.mochaDesktop.newWindow({
    id: ‘AnyPage’,
    title: ‘Any Page’,
    loadMethod: ‘iframe’,
    contentURL: ‘anypage.php’,
    width: 400,
    height: 350,
    x: 50,
    y: 105
    });
    });
    }

    if ($(’printLink’)){
    $(’printLink’).addEvent(’click’, function(e){
    new Event(e).stop();
    if(id_focus != “”){
    document.mochaDesktop.printSpecial(id_focus);
    }
    });
    }

    now the value for id_focus is the windows onfocus.
    each page that i want to allow print the conten only add the printable conten in a .

    Sorry for my english.

  34. #34
    Cristian

    now the value for id_focus is the windows onfocus.
    each page that i want to allow print the conten only add the printable conten in a div id=”PRINTAnyPage”

  35. #35
    Tim Oxley

    You know it would be cool if mocha became an official part of the mootools library, though they may want you to call it moocha or something.

  36. #36
    Newbie

    there is a problem with IE. here is the code I used :

    and what I got in IE was :
    http://img81.imageshack.us/img81/9214/59482253nb5.jpg

  37. #37
    Mercaptano

    Greg…
    Congratulations!!! It looks beautiful you’ve done a great job.

    This tool is very easy to use and pretty useful. I’m not skilled at all in programming (I’m chemist) but at least I managed to understand the application at a level that allows creating windows and manipulating their look, however, I’m having a hard time trying to use iframes. I review the file mocha.js and learn how you did to load windows with iframes triggered by a link and I can replicate it but I’m not able to have the same windows loading automatically as the user opens a web page.
    I’ve been squeezing my brains try to learn how to do this but I just don’t get it. Below is a code sample of what I tried.

    Prueba

    html, body { height: 100%; overflow: auto; }

    Ejemplo e-frame

    I hope you or someone can help to understand this.

    Greetings from mexico….

  38. #38
    Mercaptano

    Sorry here is the pice of code:

    Ejemplo e-frame

  39. #39
    Mercaptano

    One more time i hope this time it works

    Prueba

    html, body { height: 100%; overflow: auto; }

    Ejemplo e-frame

    Well this is evidence that I suck at this ñ_ñ

Leave a Reply