gui/iphone_wm_gui.js (1,418 lines of code) (raw):
// 01122011 AMD1 startWidget listWidgets getWidget implemented
/* wrapper as a module
var iphone_wm_gui = (function () {
*/
// to make sure the initialization is done only once
var init = true;
// constant
var xlinkns = 'http://www.w3.org/1999/xlink';
//var evns = 'http://www.w3.org/2001/xml-events';
// state of the widget manager: displays homepage (value=home) or executes widget (value="exec")
var state = 'home';
// convenience variables for SVG elements
var homepage = null, arrows = null, icons = null, widgetContainer = null, homebar = null, execbar = null;
// where is the index into pages of icons on the home page
var where = 0,maxwhere = 0,whereW = 0;
// array of activated widgets
var activatedWidgets = new Array();
var numActivatedWidgets = 0;
// variables for flexible layout
// variables for flexible layout
var totalWidth = 0,totalHeight = 0,iconNbHoriz = 0,iconNbVert = 0,iconsPerPage = 0;
//previous size
var previousWidth = 0,previousHeight = 0;
// to differentiate between install icon and scan dir for icons
var isThisAScan = null;
// preferred icon type
var preferredIconType = '.svg';
// adapt layout to the size of the screen
function adaptLayoutToSize() {
if (l_deb < log_level) {
alert("[UI] adaptLayoutToSize");
}
display_width = parseInt(gpac.get_option('General', 'LastWidth'));
display_height = parseInt(gpac.get_option('General', 'LastHeight'));
alert("display "+display_width+" "+display_height);
if (!gpac.fullscreen && display_width && display_height) {
gpac.set_size(display_width, display_height);
}
var tmpObject, tmpObj2;
// get size to adapt to
totalWidth = document.documentElement.viewport.width;
totalHeight = document.documentElement.viewport.height;
if (totalWidth == 0) {
totalWidth = 160;
}
if (totalHeight == 0) {
totalHeight = 280;
}
while (totalWidth < 160 || totalHeight < 280) {
totalWidth *= 4;
totalHeight *= 4;
}
// min size is 160 by 280
if (totalWidth < 160) {
totalWidth = 160;
}
if (totalHeight < 280) {
totalHeight = 280;
}
// round to lower multiple of 80
totalWidth -= totalWidth % 80;
var iconHeight = totalHeight - 120;
iconHeight -= iconHeight % 80;
// how many lines and columns of icons
iconNbHoriz = totalWidth / 80;
iconNbVert = iconHeight / 80;
totalHeight = iconHeight + 120;
// 120 is upper bar (60) + lower bar (60)
iconsPerPage = iconNbHoriz * iconNbVert;
// fix svg viewbox
document.getElementById("svg").setAttribute("viewBox", "0 0 " + totalWidth + " " + totalHeight);
// fix odd line
tmpObj2 = document.getElementById("odd");
var i, already = tmpObj2.getElementsByTagName("use").length;
//alert("odd line "+already+" "+iconNbHoriz);
for (i = already; i < iconNbHoriz; i++) {
tmpObject = document.createElement("use");
tmpObject.setAttribute("x", i * 80);
tmpObject.setAttributeNS(xlinkns, "href", (((i % 2) == 0) ? "#lightRect" : "#darkRect" ));
tmpObj2.appendChild(tmpObject);
}
// fix even line
tmpObj2 = document.getElementById("even");
already = tmpObj2.getElementsByTagName("use").length;
//alert("even line "+already+" "+iconNbHoriz);
for (i = already; i < iconNbHoriz; i++) {
tmpObject = document.createElement("use");
tmpObject.setAttribute("x", i * 80);
tmpObject.setAttributeNS(xlinkns, "href", (((i % 2) == 0) ? "#darkRect" : "#lightRect" ));
tmpObj2.appendChild(tmpObject);
}
// fix frame (black with rounded corners)
tmpObject = document.getElementById("frame");
tmpObject.setAttribute("width", totalWidth);
tmpObject.setAttribute("height", totalHeight);
tmpObject = document.getElementById("frame2");
tmpObject.setAttribute("width", totalWidth);
tmpObject.setAttribute("height", totalHeight);
// fix screen (white)
tmpObject = document.getElementById("screen");
tmpObject.setAttribute("width", totalWidth);
tmpObject.setAttribute("height", totalHeight - 120);
// fix grid back (gray)
tmpObject = document.getElementById("gridback");
tmpObject.setAttribute("width", totalWidth);
tmpObject.setAttribute("height", totalHeight - 120);
// fix icon background grid
tmpObject = document.getElementById("grid");
already = tmpObject.getElementsByTagName("use").length;
for (i = already; i < iconNbVert; i++) {
tmpObj2 = document.createElement("use");
tmpObj2.setAttribute("y", i * 80);
tmpObj2.setAttributeNS(xlinkns, "href", (((i % 2) == 0) ? "#odd" : "#even" ));
tmpObject.appendChild(tmpObj2);
}
// if there are already too many lines, remove the extra ones otherwise they are rendered on top of the lower
// part of the decoration
if (already > iconNbVert) {
while (already-- > iconNbVert) {
tmpObject.removeChild(tmpObject.lastChild);
}
}
// fix commands (lower bar)
document.getElementById("commands").setAttribute("transform", "translate(0, " + (totalHeight - 60) + ")");
document.getElementById("homeButton").setAttribute("transform", "translate(" + (totalWidth / 2) + ", 30)");
document.getElementById("right").setAttribute("transform", "translate(" + (totalWidth - 50) + ", 10)");
document.getElementById("rightW").setAttribute("transform", "translate(" + (totalWidth - 50) + ", 10)");
// fix the cuts (white rects left and right because we have no clipping)
tmpObject = document.getElementById("leftCut");
tmpObject.setAttribute("width", totalWidth);
tmpObject.setAttribute("height", totalHeight);
tmpObject.setAttribute("x", -1 - totalWidth);
tmpObject = document.getElementById("rightCut");
tmpObject.setAttribute("width", totalWidth);
tmpObject.setAttribute("height", totalHeight);
tmpObject.setAttribute("x", 1 + totalWidth);
// respace executing widgets if any
tmpObject = widgetContainer.getElementsByTagName("g");
for (i = 0; i < tmpObject.length; i++) {
var gg = tmpObject.item(i);
gg.setAttribute("transform", "translate(" + (totalWidth * (i - 1)) + ", 0)");
if (gg.firstElementChild != null) {
gg.firstElementChild.setAttribute("width", totalWidth);
gg.firstElementChild.setAttribute("height", totalHeight - 120);
}
}
}
//
// widget close on click at "Kill" button
//
function on_kill_widget() {
if (state == 'exec') {
widget_close(activatedWidgets[whereW]);
}
}
//
// widget get on click at "GetW" button
//
function on_get_widget() {
alert("on_get_widget " + WidgetManager.MPEGUStandardServiceProviders.length);
if (WidgetManager.MPEGUStandardServiceProviders.length != 0) {
upnp_renders = selector_window1();
upnp_renders.on_select = function(item) {
upnp_renders.unregister(root);
upnp_renders = null;
if (item == -1) {
return;
}
alert("upnp_renders.on_select(" + item + ")");
var device = WidgetManager.MPEGUStandardServiceProviders[item];
device.standardService.SetActionListener("listWidgets", get_widget_callback(device), true);
device.standardService.CallAction("listWidgets", new Array());
}
upnp_renders.register(root);
}
}
function get_widget_callback(device) {
return function() {
//alert("get_widget_callback");
// msgHandler is the first argument, the next arguments are from the reply to listWidgets
var act = arguments[0];
var act1 = act.GetArgumentValue("widgetCodes");
var act2 = act.GetArgumentValue("widgetNames");
//alert(act1+" "+act2);
target_widgets = selector_window2(act1.split(" "), act2.split(" "));
target_widgets.on_select = function(item) {
alert("target_widgets.on_select");
target_widgets.unregister(root);
target_widgets = null;
if (item == -1) {
return;
}
alert("target_widgets.on_select(" + item + ")");
var args = new Array();
args[0] = "widgetCode";
args[1] = item;
device.standardService.SetActionListener("getWidget", get_widget_callback2, true);
device.standardService.CallAction("getWidget", args);
}
target_widgets.register(root);
}
}
function get_widget_callback2() {
// msgHandler is the first argument, the next arguments are from the reply to listWidgets
alert("callback2-1");
var act = arguments[0];
var act1 = act.GetArgumentValue("widgetUrl");
var act2 = act.GetArgumentValue("widgetContext");
alert("callback2-2 " + act1 + " " + act2);
var wid = WidgetManager.load(act1, null, act2);
WidgetManager.on_widget_add(wid);
}
//
// creates the menu of available targets for pushing a widget elsewhere
//
function selector_window1() {
var i, count, render;
var selector = document.createElement('g'), obj, child;
selector.setAttribute('transform', 'translate(10,10)');
count = WidgetManager.MPEGUStandardServiceProviders.length;
selector.appendChild(rect(0, 0, 300, 20 * (count + 1), 'white', 'black', null));
for (i = 0; i < count; i++) {
render = WidgetManager.MPEGUStandardServiceProviders[i];
obj = createtext(render.Name, 'black', 5, 17 + (20 * i), 15, 'sans-serif');
obj.setAttribute('id', "select" + i);
selector.appendChild(obj);
obj.addEventListener('mouseover', sw1("select" + i), false);
obj.addEventListener('mouseout', sw2("select" + i), false);
obj.addEventListener('click', sw4(i), false);
}
obj = createtext('Cancel', 'rgb(0,0,120)', 55, 17 + (20 * i), 15, 'sans-serif');
obj.setAttribute('id', "canc");
selector.appendChild(obj);
obj.addEventListener('mouseover', function() { document.getElementById("canc").setAttribute("fill", "red"); }, false);
obj.addEventListener('mouseout', function() { document.getElementById("canc").setAttribute("fill", "black"); }, false);
obj.addEventListener('click', function() { upnp_renders.on_select(-1); }, false);
selector.register = function(disp) {
disp.appendChild(this);
};
selector.unregister = function(disp) {
disp.removeChild(this);
};
return selector;
}
//
// creates the menu of available targets for pushing a widget elsewhere
//
function selector_window2(codes, names) {
alert("selector_window2");
var i, count, render;
var selector = document.createElement('g'), obj, child;
selector.setAttribute('transform', 'translate(10,10)');
count = codes.length;
selector.appendChild(rect(0, 0, 300, 20 * (count + 1), 'white', 'black', null));
for (i = 0; i < count; i++) {
render = names[i];
obj = createtext(render, 'black', 5, 17 + (20 * i), 15, 'sans-serif');
obj.setAttribute('id', "selecto" + i);
selector.appendChild(obj);
obj.addEventListener('mouseover', sw1("selecto" + i), false);
obj.addEventListener('mouseout', sw2("selecto" + i), false);
obj.addEventListener('click', sw5(i), false);
}
obj = createtext('Cancel', 'rgb(0,0,120)', 55, 17 + (20 * i), 15, 'sans-serif');
obj.setAttribute('id', "cance");
selector.appendChild(obj);
obj.addEventListener('mouseover', function() { document.getElementById("cance").setAttribute("fill", "red"); }, false);
obj.addEventListener('mouseout', function() { document.getElementById("cance").setAttribute("fill", "black"); }, false);
obj.addEventListener('click', function() { target_widgets.on_select(-1); }, false);
selector.register = function(disp) {
disp.appendChild(this);
};
selector.unregister = function(disp) {
disp.removeChild(this);
};
return selector;
}
function sw4(si) {
return function() { upnp_renders.on_select(si); };
}
function sw5(si) {
return function() { target_widgets.on_select(si); };
}
//
// when deleting an executing widgets, all executing widgets to its right are moved to the left
//
function recurseMoveAfterDelete(target) {
if (target != null && target.nextElementSibling != null) {
var v = target.nextElementSibling;
recurseMoveAfterDelete(v);
v.setAttribute("transform", target.getAttribute("transform"));
}
}
//
// click on home button to switch from icons to executing widgets
//
function home_button(evt) {
if (l_deb < log_level) {
alert("[UI] home_button");
}
if (state != 'home') {
state = 'home';
widgetContainer.setAttribute('display', 'none');
homepage.setAttribute('display', 'inline');
homebar.setAttribute('display', 'inline');
execbar.setAttribute('display', 'none');
arrows.setAttribute('display', 'inline');
arrowsW.setAttribute('display', 'none');
widgetAddList.setAttribute('display', 'none');
} else {
state = 'exec';
widgetContainer.setAttribute('display', 'inline');
homepage.setAttribute('display', 'none');
homebar.setAttribute('display', 'none');
execbar.setAttribute('display', 'inline');
arrows.setAttribute('display', 'none');
arrowsW.setAttribute('display', 'inline');
widgetAddList.setAttribute('display', 'none');
}
}
// constants
var adjustFrom = "0,0";
var animDue = true;
//
// after each change of icon page, this function adjusts the visibility of arrows in the lower bar
//
function adjustwhere(animDue) {
if (l_deb < log_level) {
alert("[UI] adjust " + where + " 0 " + maxwhere);
}
document.getElementById("left").setAttribute("display", ((where > 0) ? "inline" : "none"));
document.getElementById("right").setAttribute("display", ((where < maxwhere) ? "inline" : "none"));
if (!animDue) {
icons.setAttribute("transform", 'translate(' + (-80 * iconNbHoriz * where) + ',0)');
} else {
var aw = document.createElement("animateTransform");
aw.setAttribute("attributeName", "transform");
aw.setAttribute("type", "translate");
//alert('time '+document.documentElement.getCurrentTime());
aw.setAttribute("begin", document.documentElement.getCurrentTime());
aw.setAttribute("dur", "1s");
aw.setAttribute("fill", "freeze");
aw.setAttributeNS(xlinkns, "href", "#icons");
aw.setAttribute("from", adjustFrom);
aw.setAttribute("to", (-80 * iconNbHoriz * where) + ",0");
document.documentElement.appendChild(aw);
}
adjustFrom = (-80 * iconNbHoriz * where) + ",0";
}
//
// action of the left button on the lower bar
//
function left_button() {
if (l_deb < log_level) {
alert("[UI] left button " + where + " 0");
}
if (where > 0) {
where--;
adjustwhere(true);
}
}
//
// action of the right button of the lower bar
//
function right_button() {
if (l_deb < log_level) {
alert("[UI] right button " + where + " " + maxwhere);
}
if (where < maxwhere) {
where++;
adjustwhere(true);
}
}
var adjustFromW = "0,0";
var oldwhereW = -1;
//
// after each change of icon page, this function adjusts the visibility of arrows in the lower bar
//
function adjustWhereWidgets(animDue) {
if (oldwhereW != whereW) {
// hide oldwhereW
if (oldwhereW >= 0 && activatedWidgets[oldwhereW] != null) {
WidgetManager.corein_message(activatedWidgets[oldwhereW], "hide");
}
}
if (l_deb < log_level) {
alert("[UI] adjustW " + whereW + " 0 " + (numActivatedWidgets - 1));
}
document.getElementById("leftW").setAttribute("display", ((whereW > 0) ? "inline" : "none"));
document.getElementById("rightW").setAttribute("display", ((whereW < (numActivatedWidgets - 1)) ? "inline" : "none"));
if (!animDue) {
widgetContainer.setAttribute("transform", "translate(" + (-totalWidth * whereW) + ",0)");
} else {
var aw = document.createElement("animateTransform");
aw.setAttribute("attributeName", "transform");
aw.setAttribute("type", "translate");
aw.setAttribute("begin", document.documentElement.getCurrentTime());
aw.setAttribute("dur", "1s");
aw.setAttribute("fill", "freeze");
aw.setAttributeNS(xlinkns, "href", "#widget");
aw.setAttribute("from", adjustFromW);
aw.setAttribute("to", (-totalWidth * whereW) + ",0");
document.documentElement.appendChild(aw);
}
adjustFromW = (-totalWidth * whereW) + ",0";
document.getElementById("widgetName").textContent =
(whereW >= 0 && activatedWidgets[whereW] != null ? activatedWidgets[whereW].shortName : '-');
if (oldwhereW != whereW) {
// show whereW
if (whereW >= 0 && activatedWidgets[whereW] != null) {
WidgetManager.corein_message(activatedWidgets[whereW], "show");
}
oldwhereW = whereW;
}
}
//
// action of the left button on the lower bar
//
function left_buttonW() {
if (l_deb < log_level) {
alert("[UI] left button " + whereW);
}
if (whereW > 0) {
whereW--;
adjustWhereWidgets(animDue);
}
}
//
// action of the right button of the lower bar
//
function right_buttonW() {
if (l_deb < log_level) {
alert("[UI] right button " + whereW + " " + (numActivatedWidgets - 1));
}
if (whereW < (numActivatedWidgets - 1)) {
whereW++;
adjustWhereWidgets(animDue);
}
}
//
// action of each icon, starting the matching widget
//
function activating_widget(w) {
if (l_deb < log_level) {
alert("[UI] activating widget: " + w.name);
}
widget_add(w);
}
//
// main initialization function
// init variables, then init the widget manager C code, then inits UPnP
//
function initialize() {
if (l_deb < log_level) {
alert("[UI] initialize");
}
init = false;
var display_width = parseInt(gpac.get_option('Widgets', 'LastWMWidth'));
var display_height = parseInt(gpac.get_option('Widgets', 'LastWMHeight'));
if (display_width && display_height) {
gpac.set_size(display_width, display_height);
}
root = document.documentElement;
homepage = document.getElementById('homepage');
homebar = document.getElementById('homebar');
execbar = document.getElementById('execbar');
arrows = document.getElementById('arrows');
arrowsW = document.getElementById('arrowsW');
icons = document.getElementById('icons');
widgetContainer = document.getElementById('widget');
widgetAddList = document.getElementById('widgetAddList');
/* Setup the GPAC Widget Manager - this will also scan the available widgets */
log_level = l_inf;
widget_manager_init();
WidgetManager.on_widget_remove = widget_remove;
WidgetManager.on_widget_add = widget_add;
/* register the callback to be notified of incoming widgets */
has_upnp = (typeof UPnP != 'undefined');
if (has_upnp) {
/* setting the callback to allow other devices to push their widgets */
UPnP.onMediaConnect = onMediaConnect;
/* Tell GPAC that the calls to the main Renderer (like open, ...) must be forwared to this scene */
UPnP.BindRenderer();
}
WidgetManager.coreOutShow = coreOutShowImplementation;
WidgetManager.coreOutGetAttention = coreOutGetAttentionImplementation;
WidgetManager.coreOutHide = coreOutHideImplementation;
WidgetManager.coreOutRequestDeactivate = coreOutRequestDeactivateImplementation;
WidgetManager.coreOutInstallWidget = coreOutInstallWidgetImplementation;
WidgetManager.coreOutActivateTemporaryWidget = coreOutActivateTemporaryWidgetImplementation;
WidgetManager.coreOutMigrateComponent = coreOutMigrateComponentImplementation;
WidgetManager.coreOutRequestMigrationTargets = coreOutRequestMigrationTargetsImplementation;
}
//
// implementation of core:out install widget
//
function coreOutInstallWidgetImplementation(wid, args) {
var w = widgetInstall(args[0], true, false, wid);
var ifce = getInterfaceByType(wid, "urn:mpeg:mpegu:schema:widgets:core:out:2010");
if (ifce != null) {
wmjs_core_out_invoke_reply(coreOut.installWidgetMessage, ifce.get_message("installWidget"),
wid, (w != null ? 1 : 0)); // send return code 1 = success
}
}
//
// implementation of core:out activate temporary widget
//
function coreOutActivateTemporaryWidgetImplementation(wid, args) {
var w = widgetInstall(args[0], true, true, null);
if (w != null) {
activating_widget(w);
}
var ifce = getInterfaceByType(wid, "urn:mpeg:mpegu:schema:widgets:core:out:2010");
if (ifce != null) {
wmjs_core_out_invoke_reply(coreOut.activateTemporaryWidgetMessage, ifce.get_message("activateTemporaryWidget"),
wid, (w != null ? 1 : 0)); // send return code 1 = success
}
}
//
// implementation of core:out migrate component
//
function coreOutMigrateComponentImplementation(wid, args) {
//alert("coreOutMigrateComponent "+wid.name+" "+args.length);
var comp = wid.get_component(args[0], true);
var ifce = getInterfaceByType(wid, "urn:mpeg:mpegu:schema:widgets:core:out:2010");
if (comp == null) {
log(l_err, 'Component ' + args[0] + ' cannot be found in widget ' + wid.name);
if (ifce != null) {
wmjs_core_out_invoke_reply(coreOut.migrateComponentMessage, ifce.get_message("migrateComponent"), wid, 0);
}
return;
}
if (args.length > 1 && args[1] != null) {
//WidgetManager.migrate_widget(UPnP.GetMediaRenderer(parseInt(args[1])), comp);
WidgetManager.migrate_widget(WidgetManager.get_mpegu_service_providers(parseInt(args[1])), comp);
widget_close(comp);
} else {
upnp_renders = selector_window(comp);
upnp_renders.on_select = function(item, wid) {
upnp_renders.unregister(root);
upnp_renders = null;
if (item == -1) {
return;
}
if (comp != null) {
alert("upnp_renders.on_select(" + item + "," + comp.name + ")");
//WidgetManager.migrate_widget(UPnP.GetMediaRenderer(item), comp);
WidgetManager.migrate_widget(WidgetManager.get_mpegu_service_providers(item), comp);
widget_close(comp);
}
};
upnp_renders.register(root);
}
if (ifce != null) {
wmjs_core_out_invoke_reply(coreOut.migrateComponentMessage, ifce.get_message("migrateComponent"), wid, 1); // send return code 1 = success
}
}
//
// implementation of core:out request migration targets
//
function coreOutRequestMigrationTargetsImplementation(wid, args) {
var count = UPnP.MediaRenderersCount, codes = new Array(), names = new Array(), descriptions = new Array(), i;
for (i = 0; i < count; i++) {
var render = UPnP.GetMediaRenderer(i);
codes.push("" + i);
names.push(render.Name);
descriptions.push(render.HostName + " " + render.UUID);
}
i = null;
var ifce_count = wid.num_interfaces, j;
for (j = 0; j < ifce_count; j++) {
var ifce = wid.get_interface(j);
if (ifce.type == "urn:mpeg:mpegu:schema:widgets:core:out:2010") {
i = ifce;
break;
}
}
if (i != null) {
wmjs_core_out_invoke_reply(coreOut.requestMigrationTargetsMessage, i.get_message("requestMigrationTargets"),
wid, codes, names, descriptions);
}
}
//
// implementation of core:out Show message
// this is a request by the widget to be shown
//
function coreOutShowImplementation(wid, args) {
//alert("core:out show "+wid.name);
var target = widgetContainer.firstElementChild;
var i;
for (i = 0; i < numActivatedWidgets; i++) {
//alert("is it "+activatedWidgets[i].name);
if (activatedWidgets[i] == wid) {
break;
}
target = target.nextElementSibling;
}
// here, i is the index of the current widget
//alert(" "+i+" "+numActivatedWidgets);
if (i < numActivatedWidgets) {
whereW = i;
adjustWhereWidgets(false);
}
var ifce = getInterfaceByType(wid, "urn:mpeg:mpegu:schema:widgets:core:out:2010");
if (ifce != null) {
wmjs_core_out_invoke_reply(coreOut.showMessage, ifce.get_message("show"), wid, 1); // send return code 1 = success
}
}
//
// implementation of core:out GetAttention message
// this is a request by the widget to be shown and some special signal is given
//
function coreOutGetAttentionImplementation(wid, args) {
//alert("core:out getAttention "+wid.name);
var target = widgetContainer.firstElementChild;
var i;
for (i = 0; i < numActivatedWidgets; i++) {
//alert("is it "+activatedWidgets[i].name);
if (activatedWidgets[i] == wid) {
break;
}
target = target.nextElementSibling;
}
// here, i is the index of the current widget
//alert(" "+i+" "+numActivatedWidgets);
if (i < numActivatedWidgets) {
whereW = i;
adjustWhereWidgets(false);
}
document.getElementById("getAttention").beginElement();
var ifce = getInterfaceByType(wid, "urn:mpeg:mpegu:schema:widgets:core:out:2010");
if (ifce != null) {
wmjs_core_out_invoke_reply(coreOut.getAttentionMessage, ifce.get_message("getAttention"), wid, 1); // send return code 1 = success
}
}
//
// implementation of core:out hide message
// this is a request by the widget to be hidden (some other widget (if any) is shown)
//
function coreOutHideImplementation(wid, args) {
//alert("core:out hide "+wid.name);
var target = widgetContainer.firstElementChild;
var i;
for (i = 0; i < numActivatedWidgets; i++) {
//alert("is it "+activatedWidgets[i].name);
if (activatedWidgets[i] == wid) {
break;
}
target = target.nextElementSibling;
}
// here, i is the index of the current widget
//alert("hide "+i+" "+numActivatedWidgets);
if (i < numActivatedWidgets) {
if (whereW > 0) {
whereW--;
}
else if (whereW < numActivatedWidgets - 1) {
whereW++;
}
else {
return;
}
adjustWhereWidgets(false);
}
var ifce = getInterfaceByType(wid, "urn:mpeg:mpegu:schema:widgets:core:out:2010");
if (ifce != null) {
wmjs_core_out_invoke_reply(coreOut.hideMessage, ifce.get_message("hide"), wid, 1); // send return code 1 = success
}
}
//
// implementation of core:out requestDeactivate message
// this is a request by the widget to be stopped
//
function coreOutRequestDeactivateImplementation(wid, args) {
//alert("core:out hide "+wid.name);
var target = widgetContainer.firstElementChild;
var i;
for (i = 0; i < numActivatedWidgets; i++) {
//alert("is it "+activatedWidgets[i].name);
if (activatedWidgets[i] == wid) {
break;
}
target = target.nextElementSibling;
}
// here, i is the index of the current widget
//alert("hide "+i+" "+numActivatedWidgets);
if (i < numActivatedWidgets) {
widget_close(activatedWidgets[i]);
}
var ifce = getInterfaceByType(wid, "urn:mpeg:mpegu:schema:widgets:core:out:2010");
if (ifce != null) {
wmjs_core_out_invoke_reply(coreOut.requestDeactivateMessage, ifce.get_message("requestDeactivate"), wid, 1); // send return code 1 = success
}
}
//
// WM callback for when a component is activated by its parent
//
function widget_add(w) {
log(l_inf, "widget add " + w.name);
if (!w.activated) {
if (sameFileIgnoringSVGView(w.icon, w.main)) {
// same file in icon and main
} else {
widget_launch(w, document.createElement("animation"));
}
} else if (w.multipleInstances) {
var newwid = WidgetManager.open(w.manifest, null);
widget_launch(newwid, document.createElement("animation"));
} else {
return false;
}
state = 'exec';
widgetContainer.setAttribute('display', 'inline');
homepage.setAttribute('display', 'none');
homebar.setAttribute('display', 'none');
execbar.setAttribute('display', 'inline');
arrows.setAttribute('display', 'none');
arrowsW.setAttribute('display', 'inline');
widgetAddList.setAttribute('display', 'none');
return true;
}
function sameFileIgnoringSVGView(name1, name2) {
if (name1 == name2) {
return true;
}
if (name1 == null) {
return false;
}
var i1 = name1.indexOf("#");
var i2 = name2.indexOf("#");
if (i1 < 0) {
i1 = name1.length;
}
else {
i1--;
}
if (i2 < 0) {
i2 = name2.length;
}
else {
i2--;
}
return name1.substring(0, i1) == name2.substring(0, i2);
}
//
// recompute the number of widgets loaded currently
//
function getNbWidgets() {
var i, nbWidgets = 0;
for (i = 0; i < WidgetManager.num_widgets; i++) {
var w = WidgetManager.get(i);
if (w != null && w.loaded) {
nbWidgets++;
}
}
return nbWidgets;
}
//
// just resize the window and viewport, and initialize the first time this is called
//
function resize() {
if (init) {
initialize();
}
if (document.documentElement.viewport.width == previousWidth && document.documentElement.viewport.height == previousHeight) {
return;
}
if (l_deb < log_level) {
alert("[UI] start initialize() w:" + document.documentElement.viewport.width + " h:" + document.documentElement.viewport.height);
}
adaptLayoutToSize();
// start by filling the "home page" with known icons
where = 0;
var nbWidgets = getNbWidgets();
maxwhere = ((nbWidgets - 1) - ((nbWidgets - 1) % iconsPerPage)) / iconsPerPage;
var wid;
var iconIterator = document.getElementById("icons").firstElementChild;
var position = 0;
for (i = 1; i <= WidgetManager.num_widgets; i++) {
wid = WidgetManager.get(i - 1);
// alert("build:"+wid.main+" "+wid.loaded);
if (wid.loaded) {
insert_icon(wid, position, i - 1, iconIterator);
WidgetManager.corein_message(wid, 'setSize', 'width', totalWidth, 'height', totalHeight - 120, 'dpi', 96);
position++;
if (iconIterator != null) {
iconIterator = iconIterator.nextElementSibling;
}
}
}
adjustwhere(false);
adjustWhereWidgets(false);
previousWidth = document.documentElement.viewport.width;
previousHeight = document.documentElement.viewport.height;
gpac.set_option("Widgets", "LastWMWidth", '' + previousWidth);
gpac.set_option("Widgets", "LastWMHeight", '' + previousHeight);
}
//
// function inserting an icon on the home page
//
function insert_icon(widget, position, widgetIndex, previousIcon) {
if (l_deb < log_level) {
alert("[UI] insert_icon: " + widget.shortName + " " + position + " " + widgetIndex + " WMnw:" + WidgetManager.num_widgets);
}
widget.loaded = true;
if (l_deb < log_level) {
alert("[UI] widget name: " + widget.name);
}
var icon = null, original = null;
for (var i = 0; i < widget.icons.length; i++) {
// default to the first icon even if not of the preferred type
if (i == 0) {
icon = widget.icons[0].relocated_src;
//original = widget.icons[0].original;
// alert("choosing default icon " + icon);
}
// check for preferred type
if (widget.icons[i].relocated_src.indexOf(preferredIconType) > 0) {
icon = widget.icons[i].relocated_src;
//original = widget.icons[i].original;
break;
}
}
var shortName = widget.shortName;
if (typeof shortName == 'undefined') {
shortName = widget.name.substring(0, 9);
}
createIconSVGdecoration(previousIcon, widget, (((position % iconNbHoriz) * 80) + ((80 * (position - (position % iconsPerPage))) / iconNbVert)),
((((position % iconsPerPage) - (position % iconNbHoriz)) / iconNbHoriz) * 80), "icons", icon,
shortName, widgetIndex);
}
// constant
// const corein = "urn:mpeg:mpegu:schema:widgets:core:in:2010";
//
// commodity method to empty a list of children
//
function removeAllChildren(o) {
if (o != null && o.hasChildNodes()) {
while (o.childNodes.length >= 1) {
o.removeChild(o.firstChild);
}
}
}
//
// create the home page icon with all its behaviours
//
function createIconSVGdecoration(previousIcon, widget, x, y, fatherId, iconUrl, name, widIndex) {
var g, g2;
if (l_inf < log_level) {
alert("[UI] createIconSVGdecoration " + iconUrl + " " + x + " " + y);
}
if (previousIcon != null) {
g = previousIcon;
} else {
g = document.createElement("g");
document.getElementById(fatherId).appendChild(g);
}
g.setAttribute("transform", 'translate(' + x + ',' + y + ')');
if (previousIcon != null) {
g2 = g.firstElementChild;
} else {
g2 = document.createElement("g");
g2.setAttribute("transform", 'translate(15,10)');
g.appendChild(g2);
}
if (iconUrl == null || iconUrl == "") {
iconUrl = "icons/face-surprise.svg";
}
//
// process differently cases where widget.icon == widget.main
//
var container;
if (sameFileIgnoringSVGView(iconUrl, widget.main) && widget.main.indexOf('.svg') >= 0) {
// see if the animation already exists
container = document.getElementById(name);
if (container == null) {
// if the animation does not exist yet, create it
container = media('animation', iconUrl, 50, 50);
// store the animation in the main defs
document.getElementById("mainDefs").appendChild(container);
container.setAttribute('id', name);
}
if (previousIcon == null) {
// put the container in a use
var use = document.createElement("use");
use.setAttribute('id', 'iconContainer' + name);
use.setAttributeNS(xlinkns, 'href', '#' + name);
g2.appendChild(use);
}
} else {
if (previousIcon == null) {
container = appropriateElementForMedia(iconUrl, 50, 50);
container.setAttribute('id', name);
g2.appendChild(container);
}
}
if (previousIcon == null) {
g2 = document.createElement("g");
g2.setAttribute("transform", 'translate(40,70)');
g.appendChild(g2);
var anim = createtext(name, 'white', 0, 0, 14, 'Arial Unicode MS');
anim.setAttribute("text-anchor", "middle");
anim.setAttribute("display-align", "center");
g2.appendChild(anim);
var rect = invisible_rect(80, 80);
g.appendChild(rect);
rect.addEventListener("click", csi(widget), false);
}
}
function csi(widget) {
return function(evt) { activating_widget(widget);};
}
//
// widget closing action (WM callback)
//
function widget_close(wid) {
if (wid == null) {
return;
}
if (l_inf <= log_level) {
alert('[UI] widget_close:' + wid.name);
}
// maybe inform the widget that it is going to be deactivated
WidgetManager.corein_message(wid, "deactivate");
var target = widgetContainer.firstElementChild;
var i;
for (i = 0; i < numActivatedWidgets; i++) {
if (activatedWidgets[i] == wid) {
break;
}
target = target.nextElementSibling;
}
if (target != null) {
// move next widgets back one slot
recurseMoveAfterDelete(target);
// stop the subscene
if (target.firstElementChild != null) {
target.firstElementChild.setAttributeNS(xlinkns, "href", "");
}
// end trying
widgetContainer.removeChild(target);
}
wid.deactivate();
wid.activated = false;
activatedWidgets.splice(i, 1);
numActivatedWidgets--;
whereW = (whereW >= i ? (whereW > 0 ? whereW - 1 : 0) : whereW);
adjustWhereWidgets(false);
// if no more widgets, go back to the icons
if (numActivatedWidgets == 0) {
state = 'home';
widgetContainer.setAttribute('display', 'none');
homepage.setAttribute('display', 'inline');
homebar.setAttribute('display', 'inline');
execbar.setAttribute('display', 'none');
arrows.setAttribute('display', 'inline');
arrowsW.setAttribute('display', 'none');
widgetAddList.setAttribute('display', 'none');
}
if (!wid.permanent) {
WidgetManager.unload(wid, false);
}
}
//
// widget unloading action (WM callback)
//
function widget_remove(wid) {
if (l_deb <= log_level) {
alert('[UI] widget_remove:' + wid.name);
}
widget_close(wid);
WidgetManager.unload(wid, false);
}
//
// widget launcher action
//
function widget_launch(wid, scene_container) {
if (l_inf <= log_level) {
alert('[UI] widget_launch:' + wid.name);
}
var tmp = document.createElement("g");
tmp.setAttribute("transform", "translate(" + (totalWidth * numActivatedWidgets) + ", 0)");
widgetContainer.appendChild(tmp);
var icon = null;
alert("wid: " + wid.name + "|" + wid.shortName);
if (typeof wid.shortName != 'undefined') {
var container = document.getElementById(wid.shortName);
if (container != null) {
icon = container.getAttributeNS(xlinkns, 'href');
}
}
if (icon != null &&
sameFileIgnoringSVGView(icon, wid.main) &&
endsWith(wid.main, '.svg')) {
// get the animation with id=shortName stored in mainDefs
scene_container = document.getElementById(wid.shortName);
// get the original use on it, used in the icon
var iconContainer = document.getElementById('iconContainer' + wid.shortName);
// create a new use
var use = document.createElement('use');
// point to the animation
use.setAttributeNS(xlinkns, 'href', '#' + wid.shortName);
// resize the animation
scene_container.setAttribute("width", totalWidth);
scene_container.setAttribute("height", totalHeight - 120);
// resize the original use
//should do: fix the aspect ratio conservation
var m, t = Math.abs(totalHeight - 120 - totalWidth) / 2;
if (totalWidth > totalHeight - 120) {
m = 50 / (totalHeight - 120);
iconContainer.setAttribute('transform', 'scale(' + m + ',' + m + ') translate(' + (-t) + ',0)');
} else {
m = 50 / totalWidth;
iconContainer.setAttribute('transform', 'scale(' + m + ',' + m + ') translate(0,' + (-t) + ') ');
}
// add the new use as widget execution container
tmp.appendChild(use);
wid.activate(scene_container);
} else {
scene_container.setAttribute("width", totalWidth);
scene_container.setAttribute("height", totalHeight - 120);
tmp.appendChild(scene_container);
scene_container.setAttributeNS(xlinkns, 'href', wid.main);
wid.activate(scene_container);
}
wid.activated = true;
activatedWidgets.splice(numActivatedWidgets, 0, wid);
whereW = numActivatedWidgets;
numActivatedWidgets++;
adjustWhereWidgets(false);
wid.load_component = widget_load_component;
wid.permanent = true;
wid.on_load = function () {
WidgetManager.corein_message(this, 'setSize', 'width', totalWidth, 'height', totalHeight - 120, 'dpi', 96);
};
//
if (log_level > l_inf) {
var i = 0;
alert(">>>>>>>>>>>>> " + wid.name + " interfaces:");
for (; i < wid.num_interfaces; i++) {
alert("" + wid.get_interface(i).type);
}
}
//
}
//
// widget load component (WM callback)
//
function widget_load_component(comp, is_unload) {
if (l_deb <= log_level) {
alert('[UI] widget_load_component:' + comp.name);
}
if (is_unload) {
widget_close(comp);
comp.parent = null;
} else {
widget_add(comp);
comp.permanent = false;
comp.parent = this;
}
}
var upnp_renders = null, target_widgets = null;
//
// widget remoting function
//
function on_widget_remote() {
if (WidgetManager.MPEGUStandardServiceProviders.length != 0 && numActivatedWidgets > 0) {
upnp_renders = selector_window(activatedWidgets[whereW]);
upnp_renders.on_select = function(item, wid) {
upnp_renders.unregister(root);
upnp_renders = null;
if (item == -1) {
return;
}
if (wid != null) {
alert("upnp_renders.on_select(" + item + "," + wid.name + ")");
//WidgetManager.migrate_widget(UPnP.GetMediaRenderer(item), wid);
WidgetManager.migrate_widget(WidgetManager.get_mpegu_service_providers(item), wid);
widget_close(wid);
}
};
upnp_renders.register(root);
}
}
//
// creates the menu of available targets for pushing a widget elsewhere
//
function selector_window(widget) {
var i, count, render;
var selector = document.createElement('g'), obj, child;
selector.setAttribute('transform', 'translate(10,10)');
count = WidgetManager.MPEGUStandardServiceProviders.length;
selector.appendChild(rect(0, 0, 300, 20 * (count + 1), 'white', 'black'));
for (i = 0; i < count; i++) {
render = WidgetManager.MPEGUStandardServiceProviders[i];
obj = createtext(render.Name, 'black', 5, 17 + (20 * i), 15, 'sans-serif');
obj.setAttribute('id', "selector" + i);
selector.appendChild(obj);
obj.addEventListener('mouseover', sw1("selector" + i), false);
obj.addEventListener('mouseout', sw2("selector" + i), false);
obj.addEventListener('click', sw3(i, widget), false);
}
obj = createtext('Cancel', 'rgb(0,0,120)', 55, 17 + (20 * i), 15, 'sans-serif');
obj.setAttribute('id', "cancel");
selector.appendChild(obj);
obj.addEventListener('mouseover', function(evt) { document.getElementById("cancel").setAttribute("fill", "red"); }, false);
obj.addEventListener('mouseout', function(evt) { document.getElementById("cancel").setAttribute("fill", "black"); }, false);
obj.addEventListener('click', function(evt) { upnp_renders.on_select(-1, null); }, false);
selector.register = function(disp) {
disp.appendChild(this);
};
selector.unregister = function(disp) {
disp.removeChild(this);
};
return selector;
}
function sw1(s) {
return function(evt) { document.getElementById(s).setAttribute("fill", "blue"); };
}
function sw2(s) {
return function(evt) { document.getElementById(s).setAttribute("fill", "black"); };
}
function sw3(si, widget) {
return function(evt) { upnp_renders.on_select(si, widget); };
}
//
// when a widget is pushed to here, install the widget and execute it
//
function onMediaConnect(url, src_ip) {
if (l_inf <= log_level) {
alert('[UI] onMediaConnect :\"' + url + '\"');
}
if (WidgetManager.probe(url)) {
var w = WidgetManager.open(url, src_ip);
if (w == null) {
return;
}
widget_add(w);
adjustWhereWidgets(false);
w.permanent = false;
}
}
//
// file list vars
//
var flstart = 0,fllist = null,maxFileNames = 14;
//
// create a file menu in the main screen, allowing to navigate directories and choose widget config files
//
function on_widget_add_menu() {
state = 'list';
widgetContainer.setAttribute('display', 'none');
homepage.setAttribute('display', 'none');
homebar.setAttribute('display', 'none');
execbar.setAttribute('display', 'inline');
arrows.setAttribute('display', 'none');
arrowsW.setAttribute('display', 'none');
widgetAddList.setAttribute('display', 'inline');
maxFileNames = Math.round(((iconNbVert * 80) / 25) - 1.4);
isThisAScan = false;
refillWidgetAddList(false);
}
//
// create a file menu in the main screen, allowing to navigate directories and choose a directory to scan for widgets
// and load all their icons
//
function on_dir_scan() {
state = 'list';
widgetContainer.setAttribute('display', 'none');
homepage.setAttribute('display', 'none');
homebar.setAttribute('display', 'none');
execbar.setAttribute('display', 'inline');
arrows.setAttribute('display', 'none');
arrowsW.setAttribute('display', 'none');
widgetAddList.setAttribute('display', 'inline');
maxFileNames = Math.round(((iconNbVert * 80) / 25) - 1.4);
isThisAScan = true;
refillWidgetAddList(true);
}
//
// remove all installed icons
//
function on_clean_up() {
var i;
//if (l_inf <= log_level) alert('[UI] unloading ' + WidgetManager.num_widgets + ' widgets');
for (i = WidgetManager.num_widgets - 1; i >= 0; i--) {
var w = WidgetManager.get(i);
if (w.loaded) {
alert("unloading " + w.name);
w.loaded = false;
WidgetManager.unload(w, false);
}
}
where = 0;
maxwhere = 0;
removeAllChildren(document.getElementById("icons"));
adjustwhere(false);
}
//
// install, but do not launch, the widget whose config.xml has been chosen, and return to the home page
//
function widgetInstall(uri, manual, temporary, parent_wid) {
var wid, j, count = WidgetManager.num_widgets, nbWidgets = getNbWidgets();
for (j = 0; j < count; j++) {
wid = WidgetManager.get(j);
if (wid.url == uri) {
if (wid.loaded) {
break;
}
if (temporary) {
wid.permanent = false;
}
else {
insert_icon(wid, nbWidgets, nbWidgets);
}
}
}
if (j == count) {
wid = WidgetManager.open(uri, null, parent_wid);
if (wid != null) {
if (temporary) {
wid.permanent = false;
}
else {
insert_icon(wid, nbWidgets, nbWidgets);
}
}
}
if (manual) {
return wid;
}
state = 'home';
widgetContainer.setAttribute('display', 'none');
homepage.setAttribute('display', 'inline');
homebar.setAttribute('display', 'inline');
execbar.setAttribute('display', 'none');
arrows.setAttribute('display', 'inline');
arrowsW.setAttribute('display', 'none');
removeAllChildren(widgetAddList);
maxwhere = ((nbWidgets - 1) - ((nbWidgets - 1) % iconsPerPage)) / iconsPerPage;
where = maxwhere;
adjustwhere(false);
return wid;
}
//
// clean up file list space and refill it
//
function refillWidgetAddList(flag) {
removeAllChildren(widgetAddList);
fllist = null;
flstart = 0;
fllist = gpac.enum_directory(gpac.last_working_directory, "", false);
fillWidgetAddList(flag);
}
//
// go to parent directory
//
function flUpDir(evt) {
var s = gpac.last_working_directory;
if (l_inf <= log_level) {
alert("[UI] lwd:" + gpac.last_working_directory);
}
var index = s.lastIndexOf("\\");
if (index != -1) {
gpac.last_working_directory = s.substring(0, index);
refillWidgetAddList(isThisAScan);
} else {
index = s.lastIndexOf("/");
if (index != -1) {
gpac.last_working_directory = s.substring(0, index);
refillWidgetAddList(isThisAScan);
} else {
gpac.last_working_directory = "/";
refillWidgetAddList(isThisAScan);
}
}
}
//
// go to a named directory
//
function flGoTo(newDir) {
//alert("goto "+newDir);
var s = gpac.last_working_directory;
if (s == "/") {
gpac.last_working_directory = newDir;
} else {
var c = s.charAt(s.length - 1);
if (c != '\\' && c != '/') {
s += "/";
}
gpac.last_working_directory = s + newDir;
}
//alert(gpac.last_working_directory);
refillWidgetAddList(isThisAScan);
}
//
// if the directory contains more files that can be shown, show previous page of file names
//
function flPrevFiles(evt) {
if (flstart == 0) {
return;
}
flstart -= maxFileNames;
if (flstart < 0) {
flstart = 0;
}
removeAllChildren(widgetAddList);
fillWidgetAddList(isThisAScan);
}
//
// if the directory contains more files that can be shown, show next page of file names
//
function flNextFiles(evt) {
if (flstart + maxFileNames < fllist.length) {
flstart += maxFileNames;
removeAllChildren(widgetAddList);
fillWidgetAddList(isThisAScan);
}
}
//
// scan the current directory recursively for widgets, clean up and return to home page
//
function flScanDir(evt) {
scan_directory(gpac.last_working_directory);
state = 'home';
var nbWidgets = getNbWidgets();
widgetContainer.setAttribute('display', 'none');
homepage.setAttribute('display', 'inline');
homebar.setAttribute('display', 'inline');
execbar.setAttribute('display', 'none');
arrows.setAttribute('display', 'inline');
arrowsW.setAttribute('display', 'none');
removeAllChildren(widgetAddList);
maxwhere = ((nbWidgets - 1) - ((nbWidgets - 1) % iconsPerPage)) / iconsPerPage;
where = maxwhere;
adjustwhere(false);
}
//
// scanning
//
function scan_directory(dir) {
var ii, j, count, list, w, uri, loadedWidgets = 0;
list = gpac.enum_directory(dir, '.xml;.wgt', 0);
for (ii = 0; ii < list.length; ii++) {
uri = list[ii].path + list[ii].name;
if (list[ii].directory) {
scan_directory(uri);
} else {
count = WidgetManager.num_widgets;
for (j = 0; j < count; j++) {
var wid = WidgetManager.get(j);
if (wid.loaded) {
loadedWidgets++;
}
if (wid.url == uri) {
if (wid.loaded) {
break;
}
insert_icon(wid, getNbWidgets(), j);
break;
}
}
if (j == count) {
w = WidgetManager.open(uri, null);
if (w != null) {
insert_icon(w, loadedWidgets, WidgetManager.num_widgets - 1);
}
}
}
}
}
//
// create the up, prev, next button, show current directory and as many file names as possible
// the file names are active: clicking on a directory name goes to that directory
// clicking on a file tries to load that file as a widget
//
function fillWidgetAddList(flag) {
if (flag) {
widgetAddList.appendChild(use("cartoucheflag"));
document.getElementById("dirflag").textContent = gpac.last_working_directory;
} else {
widgetAddList.appendChild(use("cartouche"));
document.getElementById("dir").textContent = gpac.last_working_directory;
}
// next lines are file names
var obj;
for (i = 0; i < (fllist.length - flstart) && i < maxFileNames; i++) {
obj = use("fileMenuElement" + i);
obj.setAttribute('transform', 'translate(0,' + (25 * (i + 1)) + ')');
widgetAddList.appendChild(obj);
document.getElementById("fileMenuElement" + i + "u").setAttributeNS(xlinkns, 'href', "#" + (fllist[i + flstart].directory ? 'folder' : 'new'));
document.getElementById("fileMenuElement" + i + "t").textContent = fllist[i + flstart].name;
if (obj.listener != null) {
obj.removeEventListener("click", obj.listener);
}
if (fllist[i + flstart].directory) {
obj.listener = createGoto(escaping(fllist[i + flstart].name));
obj.addEventListener("click", obj.listener, false);
} else if (isWidgetFileName(fllist[i + flstart].name)) {
obj.listener = createWidgetInstall(escaping(gpac.last_working_directory + '/' + fllist[i + flstart].name));
obj.addEventListener("click", obj.listener, false);
}
}
}
function createGoto(s) {
return function () {
flGoTo(s);
};
}
function createWidgetInstall(s) {
return function () {
widgetInstall(s, false, false, null);
};
}
// // // // // // // // // // // // // // //
// function library
// // // // // // // // // // // // // // //
function isWidgetFileName(s) {
if (endsWith(s, 'config.xml')) {
return true;
}
if (endsWith(s, '.wgt')) {
return true;
}
return false;
}
//
// replace globally \ with / in a string
//
function escaping(s) {
s = s.replace(/\\/g, '/');
return s;
}
//
// create rect
//
function rect(x, y, w, h, fill, stroke, id) {
var child = document.createElement('rect');
if (id != null) {
child.setAttribute('id', id);
}
child.setAttribute('x', x);
child.setAttribute('y', y);
child.setAttribute('width', w);
child.setAttribute('height', h);
child.setAttribute('fill', fill);
child.setAttribute('stroke', stroke);
return child;
}
//
// create text
//
function createtext(content, fill, x, y, size, family) {
var child = document.createElement('text');
child.setAttribute('fill', fill);
child.textContent = content;
child.setAttribute('x', x);
child.setAttribute('y', y);
child.setAttribute('font-size', size);
child.setAttribute('font-family', family);
return child;
}
//
// create invisible rect getting all events
//
function invisible_rect(w, h) {
var child = document.createElement('rect');
child.setAttribute('width', w);
child.setAttribute('height', h);
child.setAttribute('fill', 'none');
child.setAttribute('stroke', 'none');
child.setAttribute('pointer-events', 'all');
return child;
}
//
// create animation
//
function media(etype, uri, w, h) {
var child = document.createElement(etype);
child.setAttributeNS(xlinkns, 'href', uri);
child.setAttribute('width', w);
child.setAttribute('height', h);
if (etype == 'animation') {
child.setAttributeNS('http://gpac.sourceforge.net/svg-extensions', 'use-as-primary', 'false');
}
return child;
}
//
// create use
//
function use(uri) {
var child = document.createElement('use');
child.setAttributeNS(xlinkns, 'href', '#' + uri);
return child;
}
//
// create appropriate element for media reference by the given uri
//
function appropriateElementForMedia(uri, w, h) {
if (uri.indexOf('#') != -1) {
return media('animation', uri, w, h);
}
if (endsWith(uri, '.svg')) {
return media('animation', uri, w, h);
}
if (endsWith(uri, '.bt')) {
return media('animation', uri, w, h);
}
if (endsWith(uri, '.png')) {
return media('image', uri, w, h);
}
if (endsWith(uri, '.jpg')) {
return media('image', uri, w, h);
}
if (endsWith(uri, '.gif')) {
return media('image', uri, w, h);
}
if (l_war <= log_level) {
alert("[UI] WARNING: bad suffix for an icon URI: " + uri);
}
return media('image', uri, w, h);
}
//
// substitute for the useful predefined function endsWith
//
function endsWith(s1, s2) {
return s1.toLowerCase().substring(s1.length - s2.length) == s2;
}
/* wrapper as a module
// export the resize function as the resize member of iphone_wm_gui, as well as other functions
return {
resize: resize,
left_button: left_button,
right_button: right_button,
left_buttonW: left_buttonW,
right_buttonW: right_buttonW,
home_button: home_button,
on_dir_scan: on_dir_scan,
on_clean_up: on_clean_up,
on_widget_add_menu: on_widget_add_menu,
on_kill_widget: on_kill_widget,
on_get_widget: on_get_widget,
on_widget_remote: on_widget_remote,
flUpDir: flUpDir,
flPrevFiles: flPrevFiles,
flNextFiles: flNextFiles,
flScanDir: flScanDir,
get_widget_callback2: get_widget_callback2
}
}());*/
function widget_activated_and_bound(wid) {
WidgetManager.corein_message(wid, "activate");
}
function printAllFieldsOf(obj, printableName) {
var details = "fields of " + printableName + ":\n";
for (var field in obj) {
fieldContents = obj[field];
if (typeof(fieldContents) == "function") {
fieldContents = "(function)";
}
details += " " + field + ": " + fieldContents + "\n";
}
alert(details);
}