Accordion Menu Generator for the krPano Panorama Viewer

SIMULZINE#3-cover-accordion-menu-generator

An accordion menu is an often used element by GUI designers. It comes handy because it’s a “spacesaver” in rich applications that need to have their content easily accessible. Especially in mobile devices, accordions menus are found everywhere. In this post I present an accordion menu generator for the krpano panorama viewer, that recently got compatible with mobile devices (through webGL or css3D). This is also my first open source project :)

How this project started

I prepared a static version of an animated accordion menu, last year, for use in the Acropolis Virtual Tour. After some people in the krpano forums requested the code for the menu, I started to build a dynamic version which could generate a menu based on some essential parameters. Lately the project evolved and got a front-end for novice users to test and generate their menu on the fly. The code of the generated menu is highly customizable in terms of style and functionality. The code is publicly available on github, as a separete repository, and can be improved or extended with other features by anyone interested.

Essentials of an accordion in the graphical user interface

According to wikipedia: an accordion is a vertically stacked list of items (e.g. labels or thumbnails). Each item can be “expanded” or “stretched” to reveal the content associated with that item. There can be zero or more items expanded at a time, depending on the configuration. In our case I split the accordion menu in groups and events. Groups are the items that can be expanded and reveal the event buttons. A group can have numerous events. Another important aspect of our approach are formations. When a group becomes active the according formation animates the other objects to reveal the event buttons associated with it.

Variables of the generator

The following figure depicts the required user input to generate the accordion. Blue dotted lines refer to dimensions (width, height, position) and green lines refer to quantity. All dimensions are in % (percentage) of the viewers width and height. Please take into consideration that this figure is only a part of viewer.

accordion variables

figure 1
user variables to generate the accordion menu
X: x position of menu (origin top left), Y: y position of menu (origin top left), MW: width of menu, GH: group buttons height, EH: event buttons height, GN: quantity of group buttons, G1EN: quantity of event buttons for group 1

A quick look at the code

The krpano viewer is a fully functional panoramic rendering engine. It uses xml code for storing static settings and has its own dynamic scripting language, also called krpano script, when more advanced features, like custom variables and functions, are needed. When embeding the viewer into HTML, a DOM element is created that can be manipulated via javascript. This structure helps novice users to have a project up and running quickly (with the default settings), and at the same time gives developers the required tools to make unique customized stuff.

What follows is the main function (also called action) for the generation of an accordion menu based on user input. It is about sequencial placing of group/event buttons and assigning the according properties (labels, onclick events, styles, etc.) to them.


 
setParameters(); 

set(ypos,0);
set(xpos, get(varX));
set(ypos2,0);
set(xpos2, get(varX));
add(ypos,varY);


for(set(i,1), i le varGN, inc(i), 
    txtadd(pname, 'Btn_Group', get(i)); 
    txtadd(xpos_percent,get(xpos), '%');
    txtadd(ypos_percent,get(ypos), '%');
    txtadd(gformation, 'GroupFormation', get(i), '()');
    addgroupBTN(get(pname), get(xpos_percent), get(ypos_percent), get(varMW_percent), get(varGH_percent)); 
    set(plugin[%pname].onclick, get(gformation)); 
    
    mul(ypos2,i, varGH);
    add(ypos2,varY);
        if(i == 1, set(varGNx, get(varG1EN)); );  
        if(i == 2, set(varGNx, get(varG2EN)); );  
        if(i == 3, set(varGNx, get(varG3EN)););  
        if(i == 4, set(varGNx, get(varG4EN)););  
        for(set(k,1), k le varGNx, inc(k), 
            txtadd(pname, 'Btn_Group', get(i),'_event_', get(k)); 
            txtadd(xpos_percent,get(xpos), '%');
            txtadd(ypos2_percent,get(ypos2), '%');
            txtadd(gformation, 'GroupFormation', get(i), '()');
            addeventBTN(get(pname), get(xpos_percent), get(ypos2_percent), get(varew_percent), get(varEH_percent));  
            inc(ypos2,get(varEH)); 
            set(plugin[%pname].onclick, get(gformation)); 
            );
    );

Group and Event buttons are added based on the following custom functions. They are based on the textfield plugin that comes with the krpano viewer, but it can be replaced by other plugins or tailored images.


 
        addplugin(get(pname));
        set(plugin[%pname].html,[p]%1[/p]);
        set(plugin[%pname].x,%2);
        set(plugin[%pname].y,%3);
        set(plugin[%pname].width,%4);
        set(plugin[%pname].height,%5);
        set(plugin[%pname].url, plugins/textfield.swf);
        plugin[%pname].loadstyle(GroupButtonsStyle)


 
        addplugin(get(pname));
        set(plugin[%pname].html,[p]%1[/p]);
        set(plugin[%pname].x,%2);
        set(plugin[%pname].y,%3);
        set(plugin[%pname].width,%4);
        set(plugin[%pname].height,%5);
        set(plugin[%pname].url, plugins/textfield.swf);
        plugin[%pname].loadstyle(EventButtonsStyle)


 
        createGbutton(%1, %2, %3, %4, %5);
        inc(ypos,get(varGH));


 
        createEbutton(%1, %2, %3, %4, %5);


Another important aspect of the accordion are the different formations (or states) that are triggered based on which Group Button is active (as mentioned earlier). Formations are not generated on the fly (eg. dynamic). I’ve scripted the first four of them statically, so currently the menu is limited to 4 group buttons. For example the code for Group 2 is :




hideGroup3();
hideGroup1();
hideGroup4();
set(plugin[Btn_Group3].blendmode, normal);
set(plugin[Btn_Group4].blendmode, normal);
set(plugin[Btn_Group1].blendmode, normal);
set(plugin[Btn_Group2].blendmode, hardlight);
mul(varqevents2, varG2EN, varEH);
add(varg2l2,varqevents2,varGH);
txtadd(varg2l2_percent,get(varg2l2), '%');
tween(plugin[Btn_Group1].height, get(varGH_percent));
tween(plugin[Btn_Group2].height, get(varg2l2_percent));
tween(plugin[Btn_Group3].height, get(varGH_percent));
tween(plugin[Btn_Group4].height, get(varGH_percent));
set(varg2y2,get(varg2y0));
add(varg3y2, varg2y2, varg2l2);
txtadd(varg3y2_percent,get(varg3y2), '%');
add(varg4y2, varg3y2, varGH);
txtadd(varg4y2_percent,get(varg4y2), '%');
tween(plugin[Btn_Group2].y, get(varg2y0_percent));
tween(plugin[Btn_Group3].y, get(varg3y2_percent));
tween(plugin[Btn_Group4].y, get(varg4y2_percent));
showGroup2();
set(plugin[Btn_Group1].enabled,true);
set(plugin[Btn_Group2].enabled,false);
set(plugin[Btn_Group3].enabled,true);
set(plugin[Btn_Group4].enabled,true);


To name and set the onclick events of the buttons based on your preference include this in your code (for every button) :


set(plugin[Btn_Group2_event_1].html,[p]In the main Gorge 1[/p]);
set(plugin[Btn_Group2_event_1].onclick,loadscene_2());

Specifics of our krpano Accordion Menu

  • currently supports up to four Groups and six Events per Group, but can be easily extended to more
  • uses .blendmode property (currently not supported in HTML5 version)
  • can be custom styled based on your design - just edit the according style entities
  • only one group expanded at a time
  • works with text labels (eg. textfield plugin) but can be edited to work with images also
  • all dimensions are in % (percentage) of the viewers width and height.

The github repository

As mentioned earlier I’ve creted a github repository to host the code of the generator. I’m planning to extend the project with an image based accordion menu in the future like the one you can see in the Acropolis Virtual Tour when you click at the “Detail Views” button. I also hope that I get some help from other krpano developers for this next task.