gui/mpegu-wm.js (1,454 lines of code) (raw):
//This software module was originally developed by TelecomParisTech in the
//course of the development of MPEG-U Widgets (ISO/IEC 23007-1) standard.
//
//This software module is an implementation of a part of one or
//more MPEG-U Widgets (ISO/IEC 23007-1) tools as specified by the MPEG-U Widgets
//(ISO/IEC 23007-1) standard. ISO/IEC gives users of the MPEG-U Widgets
//(ISO/IEC 23007-1) free license to this software module or modifications
//thereof for use in hardware or software products claiming conformance to
//the MPEG-U Widgets (ISO/IEC 23007-1). Those intending to use this software
//module in hardware or software products are advised that its use may
//infringe existing patents.
//The original developer of this software module and his/her company, the
//subsequent editors and their companies, and ISO/IEC have no liability
//for use of this software module or modifications thereof in an implementation.
//Copyright is not released for non MPEG-U Widgets (ISO/IEC 23007-1) conforming
//products.
//Telecom ParisTech retains full right to use the code for his/her own purpose,
//assign or donate the code to a third party and to inhibit third parties from
//using the code for non MPEG-U Widgets (ISO/IEC 23007-1) conforming products.
//
//This copyright notice must be included in all copies or derivative works.
//
//Copyright (c) 2009.
//
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
//
// Authors:
// Jean Le Feuvre, Telecom ParisTech
//
/////////////////////////////////////////////////////////////////////////////////
// 01122011 AMD1 startWidget implemented
// TODO AMD1 listWidgets getWidget requestCapabilitiesList
//Initialize the main UI script
function initialize() {
//var icon;
var i, count, wid;
gpac.caption = 'MPEG-U @ Osmo4';
display_width = parseInt(gpac.get_option('Widgets', 'LastWMWidth'));
display_height = parseInt(gpac.get_option('Widgets', 'LastWMHeight'));
if (display_width && display_height) {
gpac.set_size(display_width, display_height);
} else {
display_width = gpac.get_screen_width();
display_height = gpac.get_screen_height();
}
//request event listeners on the window - GPAC specific extensions !!!
root.addEventListener('resize', on_resize, 0);
root.addEventListener('zoom', on_zoom, 0);
root.addEventListener('scroll', on_scroll, 0);
widget_default_size = 200;
scene_width = 0;
wctl_iconsize = new SFVec2f(24, 24);
icon_size = 48;
dock_height = 48;
info_height = 32;
toggle_bar_height = 16;
screen_dpi = gpac.get_horizontal_dpi();
widget_remote_candidate = null;
has_upnp = eval("(typeof(UPnP) != 'undefined');");
if (has_upnp) {
UPnP.onMediaRendererAdd = onMediaRendererAdd;
UPnP.onMediaConnect = onMediaConnect;
UPnP.BindRenderer();
upnp_renders = null;
}
/*setup dock*/
widget_screen_visible = false;
/*widget subtree*/
widget_display = new SFNode('Transform2D');
ui_root.children[0] = widget_display;
/*widget manager page*/
widget_screen = new SFNode('Layer2D');
ui_root.children[1] = widget_screen;
/*all other UI elements subtree*/
dlg_display = new SFNode('Transform2D');
ui_root.children[2] = dlg_display;
infobar = text_label('', 'MIDDLE');
ui_root.children[3] = infobar;
/*our dock*/
dock = new SFNode('Transform2D');
ui_root.children[4] = dock;
/*init the widget manager*/
Browser.loadScript('mpegu-core.js', true);
log_level = l_inf;
widget_manager_init();
WidgetManager.on_widget_remove = widget_remove;
WidgetManager.on_widget_add = widget_insert;
WidgetManager.coreOutSetSize = widget_request_size;
WidgetManager.coreOutShow = widget_request_show;
WidgetManager.coreOutHide = widget_request_hide;
WidgetManager.coreOutRequestActivate = widget_request_activate;
WidgetManager.coreOutRequestDeactivate = widget_request_deactivate;
WidgetManager.coreOutShowNotification = widget_request_notification;
WidgetManager.coreOutPlaceComponent = widget_place_component;
WidgetManager.coreOutGetAttention = widget_request_attention;
WidgetManager.coreOutInstallWidget = widget_install_widget;
WidgetManager.coreOutMigrateComponent = widget_migrate_component;
WidgetManager.coreOutRequestMigrationTargets = widget_request_migration_targets;
nb_widgets_on_screen = 0;
first_visible_widget = 0;
setup_icons();
/*restore our widgets*/
widgets_init();
//let's do the layout
layout();
}
function new_timeout(time)
{
var obj = new SFNode('TimeSensor');
obj.cycleInterval = time;
obj.start = function(when) {
var t = this.getTime();
this.startTime = when + this.getTime();
};
obj.stop = function(when) {
this.stopTime = when + this.getTime();
};
obj.on_event = null;
obj.event = function(val) {
if (this.on_event) this.on_event(val);
};
Browser.addRoute(obj, 'fraction_changed', obj, obj.event);
return obj;
}
function rectangle()
{
var obj = new SFNode('Shape');
obj.appearance = new SFNode('Appearance');
obj.appearance.material = new SFNode('Material2D');
obj.appearance.material.filled = TRUE;
obj.appearance.material.emissiveColor = new SFColor(0.7, 0.7, 0.8);
obj.appearance.material.lineProps = new SFNode('LineProperties');
obj.appearance.material.lineProps.width = 2;
obj.appearance.material.lineProps.lineColor = new SFColor(0, 0, 0);
obj.geometry = new SFNode('Curve2D');
obj.geometry.point = new SFNode('Coordinate2D');
temp = obj.geometry.type;
temp[0] = 7;
temp[1] = 1;
temp[2] = 7;
temp[3] = 1;
temp[4] = 7;
temp[5] = 1;
temp[6] = 7;
temp[7] = 6;/*close*/
obj.set_size = function(w, h) {
var hw, hh, rx, ry;
var temp;
hw = w/2;
hh = h/2;
/*compute default rx/ry*/
ry = rx = 10;
if ( (2*rx>=hw) || (2*ry>=hh)) rx = ry = 6;
temp = this.geometry.point.point;
temp[0] = new SFVec2f(hw-rx, hh);
temp[1] = new SFVec2f(hw, hh);/*bezier ctrl point*/
temp[2] = new SFVec2f(hw, hh-ry);
temp[3] = new SFVec2f(hw, -hh+ry);
temp[4] = new SFVec2f(hw, -hh);/*bezier control point*/
temp[5] = new SFVec2f(hw-rx, -hh);
temp[6] = new SFVec2f(-hw+rx, -hh);
temp[7] = new SFVec2f(-hw, -hh);/*bezier control point*/
temp[8] = new SFVec2f(-hw, -hh+ry);
temp[9] = new SFVec2f(-hw, hh-ry);
temp[10] = new SFVec2f(-hw, hh);/*bezier control point*/
temp[11] = new SFVec2f(-hw+rx, hh);
};
obj.set_color = function(r, g, b) {
this.appearance.material.emissiveColor.r = r;
this.appearance.material.emissiveColor.g = g;
this.appearance.material.emissiveColor.b = b;
};
return obj;
}
function icon_button(url, label, no_back)
{
var obj = new SFNode('Transform2D');
obj.children[0] = new SFNode('Transform2D');
obj.children[0].scale.x = 0;
obj.children[0].children[0] = rectangle();
obj.children[1] = new SFNode('Layer2D');
obj.children[1].size.x = icon_size;
obj.children[1].size.y = icon_size;
obj.children[1].children[0] = new SFNode('Inline');
obj.children[1].children[0].url[0] = url;
obj.touch = new SFNode('TouchSensor');
obj.children[1].children[1] = obj.touch;
obj.button_click = NULL;
obj.down = false;
obj.over = false;
obj.on_active = function(value) {
if (value) {
this.down = true;
} else {
if (this.down && this.over && this.button_click) this.button_click();
this.down = false;
}
};
obj.button_over = on_icon_over;
obj.on_over = function(value) {
this.over = value;
if (!no_back)
this.children[0].scale.x = value ? 1 : 0;
if (this.button_over) this.button_over(value);
};
Browser.addRoute(obj.touch, 'isOver', obj, obj.on_over);
Browser.addRoute(obj.touch, 'isActive', obj, obj.on_active);
obj.label = label;
obj.hide = function() { this.scale.x = this.scale.y = 0;};
obj.show = function() { this.scale.x = this.scale.y = 1;};
obj.set_size = function(x, y) {
this.children[0].children[0].set_size(x, y);
this.children[1].size.x = x;
this.children[1].size.y = y;
};
return obj;
}
function text_label(label, justify)
{
var obj = new SFNode('Transform2D');
obj.children[0] = new SFNode('Shape');
obj.children[0].appearance = new SFNode('Appearance');
obj.children[0].appearance.material = new SFNode('Material2D');
obj.children[0].appearance.material.filled = TRUE;
obj.children[0].appearance.material.emissiveColor = new SFColor(0, 0, 0);
obj.children[0].geometry = new SFNode('Text');
obj.children[0].geometry.string[0] = label;
obj.children[0].geometry.fontStyle = new SFNode('FontStyle');
obj.children[0].geometry.fontStyle.justify[0] = justify;
obj.children[0].geometry.fontStyle.justify[1] = 'MIDDLE';
obj.children[0].geometry.fontStyle.size = 20;
obj.set_label = function(value) {
this.children[0].geometry.string[0] = value;
};
return obj;
}
function text_rect(label)
{
var obj = new SFNode('Transform2D');
obj.children[0] = rectangle();
obj.children[0].set_color(0.7, 0.7, 0.8);
obj.children[1] = new SFNode('Shape');
obj.children[1].appearance = new SFNode('Appearance');
obj.children[1].appearance.material = new SFNode('Material2D');
obj.children[1].appearance.material.filled = TRUE;
obj.children[1].appearance.material.emissiveColor = new SFColor(0, 0, 0);
obj.children[1].geometry = new SFNode('Text');
obj.children[1].geometry.string[0] = label;
obj.children[1].geometry.fontStyle = new SFNode('FontStyle');
obj.children[1].geometry.fontStyle.justify[0] = 'MIDDLE';
obj.children[1].geometry.fontStyle.justify[1] = 'MIDDLE';
obj.children[1].geometry.fontStyle.size = 20;
obj.children[2] = new SFNode('TouchSensor');
obj.set_size = function(w, h) {
this.children[0].set_size(w, h);
};
obj.over = false;
obj.on_over = function(value) {
this.children[0].set_color(0.7, value ? 0.5 : 0.7, 0.8);
this.over = value;
};
Browser.addRoute(obj.children[2], 'isOver', obj, obj.on_over);
obj.down = false;
obj.button_click = null;
obj.on_active = function(value) {
if (value) {
this.down = true;
} else {
if (this.down && this.over && this.button_click) this.button_click();
this.down = false;
}
};
Browser.addRoute(obj.children[2], 'isActive', obj, obj.on_active);
return obj;
}
function new_widget_control(widget)
{
var obj = new SFNode('Transform2D');
obj.children[0] = new SFNode('Transform2D');
obj.children[0].children[0] = rectangle();
obj.children[0].children[1] = new SFNode('TouchSensor');
obj.component_bound=false;
obj.show_ctrl = true;
obj.onClick = function(value) {
if (!value) return;
this.show_ctrl = !this.show_ctrl;
if (this.show_ctrl) {
var i, comps, idx;
this.children[0].children[0].appearance.material.transparency = 0;
this.children[1].scale.x = 1;
this.children[3].scale.x = 1;
for (i=0; i<widget_display.children.length; i++) {
if (widget_display.children[i]==this) continue;
if (widget_display.children[i].show_ctrl) {
widget_display.children[i].onClick(true);
}
}
//widget is a component, do not push on top but hide some controls
if (widget.is_component) {
if (this.component_bound) {
this.children[1].children[0].hide(); //close
this.children[1].children[1].hide(); //remove
this.children[1].children[4].hide(); //resize
}
return;
}
//otherwise push widget on top
idx=0;
widget_display.removeChildren[idx++] = this;
widget_display.addChildren[idx++] = this;
//and push components
comps = widget.components;
for (i=0; i<comps.length; i++) {
if (comps[i].widget_control.component_bound) {
widget_display.removeChildren[idx++] = comps[i].widget_control;
widget_display.addChildren[idx++] = comps[i].widget_control;
}
}
} else {
this.children[0].children[0].appearance.material.transparency = 1;
this.children[1].scale.x = 0;
this.children[3].scale.x = 0;
}
};
Browser.addRoute(obj.children[0].children[1], 'isActive', obj, obj.onClick);
obj.children[1] = new SFNode('Transform2D');
obj.children[1].children[0] = icon_button('icons/process-stop.svg', 'Close', 0);
obj.children[1].children[0].button_click = function() {
if (widget.discardable) widget_remove(widget);
else widget_close(widget, 0);
};
obj.children[1].children[1] = icon_button('icons/user-trash.svg', 'Uninstall', 0);
obj.children[1].children[1].button_click = function() { widget_remove(widget); }
obj.children[1].children[2] = icon_button('icons/applications-internet.svg', 'Push to remote display', 0);
obj.children[1].children[2].button_click = function() {
if (has_upnp && UPnP.MediaRenderersCount) {
widget_remote_candidate = widget;
on_upnpopen();
}
};
obj.children[1].children[3] = icon_button('icons/dialog-information.svg', 'Widget Information', 0);
obj.children[1].children[3].button_click = function() {
display_widget_info(widget);
};
obj.children[1].children[4] = icon_button('icons/media-record.svg', 'Resize', 1);
obj.children[1].children[4].children[1].children[2] = new SFNode('PlaneSensor2D');
obj.children[1].children[4].children[1].children[2].maxPosition = new SFVec2f(-1, -1);
obj.prev_x=0;
obj.prev_y=0;
obj.onSize = function(value) {
if (widget.width + 2*(value.x - this.prev_x)<0) return;
if (widget.height + 2*(this.prev_y-value.y)<0) return;
widget.width += 2*(value.x - this.prev_x);
this.prev_x = value.x;
widget.height += 2*(this.prev_y - value.y);
this.prev_y = value.y;
this.set_size(widget.width, widget.height);
};
Browser.addRoute(obj.children[1].children[4].children[1].children[2], 'translation_changed', obj, obj.onSize);
obj.children[2] = new SFNode('Layer2D');
obj.inline = new SFNode('Inline');
obj.children[2].children[0] = obj.inline;
obj.children[3] = new SFNode('Transform2D');
obj.children[3].children[0] = new SFNode('Shape');
obj.children[3].children[0].appearance = new SFNode('Appearance');
obj.children[3].children[0].appearance.material = new SFNode('Material2D');
obj.children[3].children[0].appearance.material.filled = TRUE;
obj.children[3].children[0].appearance.material.transparency = 0.5;
obj.children[3].children[0].appearance.material.emissiveColor = new SFColor(0.6, 0.6, 0.6);
obj.children[3].children[0].geometry = new SFNode('Rectangle');
obj.children[3].children[0].geometry.size = new SFVec2f(50, 50);
obj.children[3].children[1] = new SFNode('PlaneSensor2D');
obj.children[3].children[1].maxPosition = new SFVec2f(-1, -1);
obj.children[3].children[1].offset = new SFVec2f(widget.x, widget.y);
obj.onMove = function(value) {
if (this.maximized) return;
this.translation = value;
widget.x = value.x;
widget.y = value.y;
this.refresh_layout(false, null);
};
Browser.addRoute(obj.children[3].children[1], 'translation_changed', obj, obj.onMove);
obj.children[3].children[2] = new SFNode('TouchSensor');
obj.last_ts = 0;
obj.onMaximize = function(value, timestamp) {
if (!value) return;
if (timestamp - this.last_ts < 0.5) {
if (this.maximized) {
this.maximized = false;
this.translation.x = widget.x;
this.translation.y = widget.y;
this.set_size(this.prev_width, this.prev_height);
} else {
this.maximized = true;
this.prev_width = widget.width;
this.prev_height = widget.height;
this.translation.x = 0;
this.translation.y = -info_height;
this.set_size(display_width, display_height - 2*info_height);
}
}
this.last_ts = timestamp;
};
Browser.addRoute(obj.children[3].children[2], 'isActive', obj, obj.onMaximize);
obj.set_size = function(w, h) {
var i, x, s;
s = 24;
this.children[2].size.x = w;
this.children[2].size.y = h;
this.children[1].children[0].translation.y = this.children[1].children[1].translation.y = this.children[1].children[2].translation.y = this.children[1].children[3].translation.y = this.children[1].children[4].translation.y = h/2 + s/2;
this.children[0].children[0].set_size(w+s, h+s);
this.children[3].children[0].geometry.size.x = w;
this.children[3].children[0].geometry.size.y = h;
this.children[1].children[0].set_size(s, s);
this.children[1].children[1].set_size(s, s);
this.children[1].children[2].set_size(s, s);
this.children[1].children[3].set_size(s, s);
this.children[1].children[4].set_size(s, s);
this.children[1].children[0].translation.x = -w/2;
this.children[1].children[1].translation.x = -w/4;
this.children[1].children[2].translation.x = 0;
this.children[1].children[3].translation.x = w/4;
this.children[1].children[4].translation.x = w/2;
//set widget input params
widget.width = w;
widget.height = h;
widget.set_input('width', w);
widget.set_input('height', h);
this.refresh_layout(true, null);
//call core:in
WidgetManager.corein_message(widget, 'setSize', 'width', w, 'height', w, 'dpi', screen_dpi);
};
obj.refresh_layout = function(send_resize, comp_target) {
var i;
var x, y, w, h, scale_x, scale_y;
var comps;
/*local to subscene transformation not known*/
if (!this.sub_w) return;
if (!this.sub_h) return;
comps = widget.components;
for (i=0; i<comps.length; i++) {
var comp = comps[i];
if (!comp.widget_control.component_bound) continue;
//compute scale from Widget Manager coord system to widget internal coordinate system
scale_x = this.sub_vp_w / this.sub_w;
scale_y = this.sub_vp_h / this.sub_h;
w = comp.widget_control.place_w * scale_x;
h = comp.widget_control.place_h * scale_y;
x = this.translation.x - widget.width/2 + this.sub_vp_x + comp.widget_control.place_x * scale_x + w/2;
comp.widget_control.translation.x = x;
y = widget.height/2 + this.translation.y - h/2 - this.sub_vp_y - comp.widget_control.place_y * scale_y;
comp.widget_control.translation.y = y;
if (send_resize || (comp_target==comp))
comp.widget_control.set_size(w, h);
}
};
obj.hide = function() {
this.scale.x = 0;
WidgetManager.corein_message(widget, 'hide');
};
obj.show = function() {
this.scale.x = 1;
WidgetManager.corein_message(widget, 'show');
};
obj.show_remote = function () {
if (WidgetManager.upnp && UPnP.MediaRenderersCount) {
this.children[1].children[2].show();
} else {
this.children[1].children[2].hide();
}
};
obj.show_remove = function(show) {
if (show) this.children[1].children[1].show();
else this.children[1].children[1].hide();
};
obj.flash = function() {
var time = new_timeout(0.25);
time.loop = true;
time.ctrl = this;
time.on_event = function(val) {
var scale = (val<0.5) ? 1+val : 2-val;
this.ctrl.scale.x = this.ctrl.scale.y = scale;
};
time.stop(1);
time.start(0);
};
obj.maximized = false;
obj.show_remote();
obj.onClick(true);
return obj;
}
function on_icon_over(value)
{
infobar.set_label(value ? this.label : '');
}
function display_widget_info(wid)
{
var info_dlg = new SFNode('Transform2D');
var i, j, k, info;
var y, txt, pref;
infobar.set_label('Widget ' + wid.name + ' Information');
info = text_rect('Close');
info_dlg.children[0] = info;
info.button_click = function() {
dlg_display.children.length = 0;
widget_display.scale.x = 1;
infobar.set_label('');
layout();
};
info = text_rect('Widget Metadata');
info_dlg.children[info_dlg.children.length] = info;
info.visible = false;
info.button_click = function() {
this.visible = !this.visible;
layout();
};
i=3;
info.children[i++] = text_label('id: ' + wid.identifier + ' - shortname: '+wid.shortName + ' - name: '+wid.name, 'BEGIN');
info.children[i++] = text_label('version: '+wid.version, 'BEGIN');
info.children[i++] = text_label('content type: ' + wid.mainMimeType + ' - content encoding: '+wid.mainEncoding, 'BEGIN');
info.children[i++] = text_label('default size: Width = ' + wid.defaultWidth + ' Height = '+wid.defaultHeight, 'BEGIN');
info.children[i++] = text_label('license: '+wid.license, 'BEGIN');
info.children[i++] = text_label('license ref: '+wid.licenseHref, 'BEGIN');
info.children[i++] = text_label('description: '+wid.description, 'BEGIN');
info.children[i++] = text_label('author name: '+wid.authorName + ' (mail: '+wid.authorEmail+')', 'BEGIN');
info.children[i++] = text_label('author href: '+wid.authorHref, 'BEGIN');
info.children[i++] = text_label('view modes: '+wid.viewmodes, 'BEGIN');
info.children[i++] = text_label('UUID: '+wid.uuid, 'BEGIN');
info.children[i++] = text_label('Discardable: '+wid.discardable, 'BEGIN');
info.children[i++] = text_label('Muliple Instances: '+wid.discardable, 'BEGIN');
var icons = wid.icons;
for (j=0; j<icons.length; j++) {
info.children[i++] = text_label('icon #'+(j+1)+': ' + icons[j].src, 'BEGIN');
}
info = text_rect('Widget Manager Info');
info_dlg.children[info_dlg.children.length] = info;
info.visible = false;
info.button_click = function() {
this.visible = !this.visible;
layout();
};
i=3;
info.children[i++] = text_label('nb instances: '+wid.num_instances + ' nb components: '+wid.num_components, 'BEGIN' );
info.children[i++] = text_label('Permanently installed: '+wid.permanent + ' - is component: '+wid.is_component, 'BEGIN' );
if (wid.is_component) {
info.children[i++] = text_label('parent widget name' + wid.parent.name, 'BEGIN');
}
if (wid.originating_device_ip) {
info.children[i++] = text_label('Widget was pushed from device IP '+wid.originating_device_ip, 'BEGIN' );
}
info.children[i++] = text_label('Section name in GPAC config file: '+wid.section, 'BEGIN' );
info.children[i++] = text_label('UA Locale: ' + gpac.get_option('Systems', 'LanguageName') + ' (' + gpac.get_option('Systems', 'Language2CC') + ')', 'BEGIN');
info.children[i++] = text_label('widget src: ' + wid.url , 'BEGIN');
info.children[i++] = text_label('config src: ' + wid.manifest , 'BEGIN');
info.children[i++] = text_label('content src : '+wid.localizedSrc, 'BEGIN' );
pref = wid.features;
info = text_rect('Features (' + pref.length + ')' );
info_dlg.children[info_dlg.children.length] = info;
info.visible = false;
info.button_click = function() {
this.visible = !this.visible;
layout();
};
i=3;
for (j=0; j<pref.length; j++) {
info.children[i++] = text_label('Feature #'+(j+1)+' name=\''+pref[j].name+'\' required=\''+pref[j].required+'\'', 'BEGIN');
}
pref = wid.preferences;
info = text_rect('Preferences ('+pref.length+')');
info_dlg.children[info_dlg.children.length] = info;
info.visible = false;
info.button_click = function() {
this.visible = !this.visible;
layout();
};
i=3;
for (j=0; j<pref.length; j++) {
var val = pref[j].value;
if (val == '') val = gpac.get_option(wid.section, pref[j].name);
info.children[i++] = text_label('Preference #'+(j+1)+' name=\''+pref[j].name+'\' value=\''+val+'\' readOnly=\''+pref[j].readonly +'\'', 'BEGIN');
}
info = text_rect('Migration Context', 'BEGIN');
info_dlg.children[info_dlg.children.length] = info;
info.visible = false;
info.button_click = function() {
this.visible = !this.visible;
layout();
};
i=3;
txt=wid.get_context();
while (1) {
var idx = txt.indexOf('\n', 0);
if (idx>0) {
info.children[i++] = text_label(txt.substring(0, idx), 'BEGIN');
txt = txt.substring(idx+1, txt.length);
} else {
info.children[i++] = text_label(txt, 'BEGIN');
break;
}
}
info_dlg.ifce_idx = info_dlg.children.length;
info = text_rect('Interfaces (count: ' + wid.num_interfaces + ' - bound: ' + wid.num_bound_interfaces+')', 'BEGIN');
info_dlg.children[info_dlg.ifce_idx] = info;
info.visible = false;
info.button_click = function() {
this.visible = !this.visible;
layout();
};
i=3;
for (j=0; j<wid.num_interfaces; j++) {
var idx;
var ifce = wid.get_interface(j);
var item = text_rect('Interface #' + (j+1) + ' type: '+ifce.type);
info.children[i++] = item;
item.visible = false;
item.button_click = function() {
this.visible = !this.visible;
layout();
};
idx=3;
item.children[idx++] = text_label('Multiple Binding: '+ifce.multipleBinding + ' - Service provider: '+ ifce.serviceProvider + ' - bound: ' + wid.is_interface_bound(ifce) , 'BEGIN');
for (k=0; k<ifce.num_messages; k++) {
var string, l;
var msg = ifce.get_message(k);
string = ' Message #'+ (k+1) + ': ' + msg.name + '(';
for (l=0; l<msg.num_params; l++) {
par = msg.get_param(l);
string += (par.is_input ? 'in' : 'out') + ':' +par.name + ' ';
}
string += ')';
item.children[idx++] = text_label(string, 'BEGIN');
}
}
info_dlg.set_size = function(w, h) {
var i, j, y, dy;
y = h/2 - 20;
for (i=0; i<this.children.length; i++) {
var item = this.children[i];
item.translation.x = 0;
item.translation.y = y;
item.set_size(w, 20);
y -= 20;
if (!i) continue;
dy = 0;
for (j=3; j<item.children.length; j++) {
if (item.visible) {
item.children[j].scale.x = 1;
dy -= 20;
item.children[j].translation.y = dy;
if (i<this.ifce_idx) {
item.children[j].translation.x = -w/2+10;
} else {
item.children[j].set_size(w-20, 20);
var ddy=0;
var k, sitem;
sitem = item.children[j];
for (k=3; k<sitem.children.length; k++) {
if (item.children[j].visible) {
sitem.children[k].scale.x = 1;
sitem.children[k].translation.x = -w/2+10;
ddy -= 20;
sitem.children[k].translation.y = ddy;
} else {
sitem.children[k].scale.x = 0;
}
}
dy+=ddy;
}
} else {
item.children[j].scale.x = 0;
}
}
y += dy;
}
};
dlg_display.children[0] = info_dlg;
widget_display.scale.x = 0;
layout();
}
function widget_insert(widget)
{
/*insert the widget icon*/
if (widget.permanent && !widget.is_component)
insert_widget_icon(widget, 0);
/*and load the widget - comment this line to disable auto load of widget*/
widget_launch(widget);
}
function setup_icons()
{
var icon;
//Widgets Icon
icon = icon_button('icons/applications-system.svg', 'Available Widgets', 0);
icon.button_click = function () {
widget_screen_visible = !widget_screen_visible;
layout();
};
dock.children[0] = icon;
//Get Widget Icon
icon = icon_button('icons/document-save.svg', 'Get Widget', 0);
icon.button_click = function () {
widget_get();
};
dock.children[1] = icon;
//Widgets add Icon
icon = icon_button('icons/list-add.svg', 'Add Widgets', 0);
icon.button_click = function () {
widget_browse();
};
dock.children[2] = icon;
icon = icon_button('icons/user-trash.svg', 'Remove all widgets', 0);
icon.button_click = function () {
while (1) {
var wid = WidgetManager.get(0);
if (wid==null) break;
widget_close(wid, 1);
}
widget_screen.children.length = 0;
layout();
};
dock.children[3] = icon;
//exit Icon
icon = icon_button('icons/emblem-unreadable.svg', 'Exit', 0);
icon.button_click = function() { gpac.exit(); };
dock.children[4] = icon;
}
/*dock layout*/
function dock_layout() {
var i;
dock.translation.y = (dock_height - display_height)/2;
infobar.translation.y = display_height/2 - info_height/2;
num_in_dock = dock.children.length;
tot_len = num_in_dock*icon_size;
if (tot_len>display_width) {
start_x = (icon_size-display_width)/2;
} else {
start_x = (icon_size-tot_len)/2;
}
/*translate / size all items in the dock*/
for (i=0;i<num_in_dock; i++) {
dock.children[i].set_size(icon_size, icon_size);
dock.children[i].translation.x = start_x + i*icon_size;
}
}
function widget_screen_layout(dir)
{
var count, i, start_x, start_y, spread_x, nb_wid_h, nb_wid_v, nb_wid;
if (!widget_screen_visible) {
widget_screen.size.x = 0;
widget_screen.size.y = 0;
return;
}
widget_screen.size.x = display_width;
widget_screen.size.y = display_height;
start_x = (icon_size/2-display_width)/2;
start_y = (display_height-icon_size/2)/2 - info_height;
start_x = (icon_size-display_width)/2;
start_y = (display_height-icon_size)/2 - icon_size/2 - info_height;
count = widget_screen.children.length;
if (first_visible_widget<0) first_visible_widget=0;
for (i=0; i<count; i++) {
var wid = widget_screen.children[i];
wid.hide();
}
nb_wid_h = Math.floor(display_width / icon_size);
if (!nb_wid_h) nb_wid_h=1;
nb_wid_v = Math.floor((display_height-dock_height-icon_size) / icon_size);
if (!nb_wid_v) nb_wid_v=1;
spread_x = (display_width / nb_wid_h) - icon_size;
start_x += spread_x/2;
nb_wid = (nb_wid_h*nb_wid_v);
if (dir<0) {
first_visible_widget -= nb_wid;
if (first_visible_widget < 0) first_visible_widget = 0;
}
else if (dir>0) {
first_visible_widget += nb_wid;
}
for (i=0; i<count; i++) {
var wid;
if (i +first_visible_widget >= count) {
break;
}
wid = widget_screen.children[i +first_visible_widget];
wid.show();
wid.set_size(icon_size, icon_size);
wid.translation.x = start_x;
wid.translation.y = start_y;
start_x += icon_size + spread_x;
if (start_x + icon_size / 2 >= display_width/2) {
start_x = (icon_size-display_width)/2 + spread_x/2;
start_y -= icon_size;
}
nb_widgets_on_screen = i+1;
if (start_y - icon_size < (dock_height-display_height)/2) {
i++;
break;
}
}
}
//performs layout on all contents
function layout() {
var i, list, start_x;
gpac.set_option('Widgets', 'LastWMWidth', '' + display_width);
gpac.set_option('Widgets', 'LastWMHeight', '' + display_height);
if (WidgetManager.num_widgets) {
dock.children[0].show();
} else {
dock.children[0].hide();
}
if (dlg_display.children.length) {
widget_display.scale.x = 0;
widget_screen_visible = false;
}
//layout all icons in the dock
dock_layout();
widget_screen_layout(0);
if (dlg_display.children.length) {
list = dlg_display.children;
for (i=0; i<list.length; i++) {
var dlg = list[i];
if (typeof (dlg.set_size) != 'undefined') dlg.set_size(display_width, display_height-icon_size-info_height);
dlg.translation.y = (icon_size-info_height)/2;
}
}
else if (widget_screen_visible) {
widget_display.scale.x = 0;
} else {
widget_display.scale.x = 1;
list = widget_display.children;
for (i=0; i<list.length; i++) {
var widctrl = list[i];
if (widctrl.maximized) {
widctrl.translation.y = - info_height;
widctrl.set_size(display_width, display_height - 2*info_height);
}
}
}
}
//resize event callback
function on_resize(evt) {
display_width = evt.width;
display_height = evt.height;
layout();
}
//zoom event callback
function on_zoom(evt) {
display_width = evt.width;
display_height = evt.height;
layout();
}
//scroll event callback
function on_scroll(evt) {
layout();
}
//starts a widget
function on_widget_launch() {
if (this.widget.visible) {
var awid;
if (!this.widget.multipleInstances) return;
awid = WidgetManager.open(this.widget.manifest, null);
widget_launch(awid);
} else {
widget_launch(this.widget);
}
}
function widget_get_icon(widget)
{
var icon = 'icons/process-stop.svg';
var preferredIconType = '.svg';
for (var i = 0; i < widget.icons.length; i++) {
icon = widget.icons[i].relocated_src;
if (widget.icons[i].relocated_src.indexOf(preferredIconType) > 0) {
break;
}
}
return icon;
}
//initialize GPAC widget manager and load all widgets
function widgets_init() {
count = WidgetManager.num_widgets;
for (i=0; i<count; i++) {
wid = WidgetManager.get(i);
if (wid == null) continue;
wid.device = null;
wid.device_ip = null;
if (wid.in_panel == true) {
icon = icon_button(widget_get_icon(wid), wid.name, 0);
icon.tooltip = wid.name;
icon.widget = wid;
icon.button_click = on_widget_launch;
wid.icon_dock = icon;
widget_screen.children[widget_screen.children.length] = wid.icon_dock;
}
if (wid.visible) {
widget_launch(wid);
}
}
}
function on_widget_size(value) {
//remember variables
this.width = value.x;
this.height = value.y;
//and set widget input params
this.set_input('width', value.x);
this.set_input('height', value.y);
}
function on_widget_move(value) {
this.x = value.x;
this.y = value.y;
}
//widget close function
function widget_close(widget, force_remove)
{
var is_comp = widget.is_component;
if (widget.visible) {
widget.visible = false;
WidgetManager.corein_message(widget, 'hide');
WidgetManager.corein_message(widget, 'deactivate');
widget.deactivate();
widget.scene_container.removeChildren[0] = widget.widget_control;
/*force disconnect of main resource - we do this because we are not sure when the widget_control will be destroyed due to JS GC*/
widget.widget_control.inline.url.length = 0;
}
if (!is_comp && (!widget.permanent || force_remove)) {
WidgetManager.unload(widget, false);
}
}
function on_widget_close(value) {
widget_close(this, 0);
}
//widget remove function (close and unregister)
function widget_remove(wid) {
if (typeof(wid.icon_dock) != 'undefined')
widget_screen.removeChildren[0] = wid.icon_dock;
widget_close(wid, 0);
layout();
}
function on_widget_control(value)
{
var i, count;
if (!value) return;
count = this.scene_container.children.length;
for (i=0; i<count; i++) {
if (this.scene_container.children[i] == this.widget_control) {
this.scene_container.removeChildren[0] = this.widget_control;
this.scene_container.children[this.scene_container.children.length] = this.widget_control;
return;
}
}
}
//widget launcher function
function widget_launch(wid) {
var widg_ctrl;
//assign default size to the widget
if (wid.width == undefined) {
wid.width = wid.defaultWidth;
if (wid.width == 0) wid.width = widget_default_size;
}
if (wid.height == undefined) {
wid.height = wid.defaultHeight;
if (wid.height == 0) wid.height = widget_default_size;
}
if (wid.x== undefined) wid.x = 0;
if (wid.y== undefined) wid.y = 0;
widg_ctrl = new_widget_control(wid);
widg_ctrl.component_bound = false;
wid.visible = true;
widg_ctrl.set_size(wid.width, wid.height);
widg_ctrl.translation.x = wid.x;
widg_ctrl.translation.y = wid.y;
wid.widget_control = widg_ctrl;
wid.scene_container = widget_display;
widg_ctrl.show_remove( (!wid.discardable && wid.icon_dock) ? 1 : 0);
widg_ctrl.sub_width = 0;
widg_ctrl.sub_height = 0;
widg_ctrl.sub_x = 0;
widg_ctrl.sub_y = 0;
widg_ctrl.sub_vp_w = 0;
widg_ctrl.sub_vp_h = 0;
widg_ctrl.inline.addEventListener('gpac_vp_changed',
function(evt) {
widg_ctrl.sub_vp_w = evt.width;
widg_ctrl.sub_vp_h = evt.height;
widg_ctrl.sub_vp_x = evt.offset_x;
widg_ctrl.sub_vp_y = evt.offset_y;
widg_ctrl.sub_w = evt.vp_width;
widg_ctrl.sub_h = evt.vp_height;
widg_ctrl.refresh_layout(true, null);
},
0);
/*this will setup the scene graph for the widget in order to filter input and output communication pins*/
wid.activate(widg_ctrl.inline);
widg_ctrl.inline.url[0] = wid.main;
widget_display.addChildren[0] = widg_ctrl;
/*send notifications once the widget scene is loaded*/
wid.on_load = function () {
WidgetManager.corein_message(this, 'activate');
WidgetManager.corein_message(this, 'show');
WidgetManager.corein_message(this, 'setSize', 'width', 50, 'height', 50, 'dpi', 96);
};
if (widget_screen_visible) {
widget_screen_visible = 0;
layout();
}
//
if (log_level > l_inf) {
var i = 0;
alert(">>>>>>>>>>>>> "+wid.name+" interfaces:");
for (;i < wid.num_interfaces; i++) {
alert(""+wid.get_interface(i).type);
}
}
//
}
//core out install widget implementation JCD
function widget_install_widget(widget, args)
{
var uri = args[0], j;
var count = WidgetManager.num_widgets;
for (j=0; j<count; j++) {
var wid = WidgetManager.get(j);
if (wid.url==uri) break;
}
if (j==count) {
new_wid = WidgetManager.open(uri, null);
if (new_wid!=null) {
insert_widget_icon(new_wid, 1);
}
}
}
//core out migrate component implementation JCD
function widget_migrate_component(widget, args)
{
if (has_upnp && UPnP.MediaRenderersCount) {
widget_remote_candidate = widget.get_component(args[0]);
if (widget_remote_candidate==null) {
log(l_err, 'Component '+args[0]+' cannot be found in widget '+widget.name);
return;
}
if (args.length > 1 && args[1] != null) {
var render = WidgetManager.MPEGUStandardServiceProviders[parseInt(args[1])];
WidgetManager.migrate_widget(render, widget_remote_candidate);
widget_close(widget_remote_candidate, 0);
widget_remote_candidate = null;
} else {
on_upnpopen();
}
}
}
// core out request migration targets JCD
function widget_request_migration_targets(wid, args)
{
var count = WidgetManager.MPEGUStandardServiceProviders.length,
codes = new Array(), names = new Array(), descriptions = new Array(), i;
for (i = 0; i < count; i++) {
var render = WidgetManager.MPEGUStandardServiceProviders[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);
}
}
function widget_request_size(widget, args)
{
if (args.length==2) {
w = (typeof args[0] == 'string') ? parseInt(args[0]) : args[0];
h = (typeof args[1] == 'string') ? parseInt(args[1]) : args[1];
widget.widget_control.set_size(w, h);
}
}
function widget_request_show(widget, args)
{
widget.widget_control.show();
}
function widget_request_hide(widget, args)
{
widget.widget_control.hide();
}
function widget_request_activate(widget, args)
{
if (!widget.visible)
widget_launch(widget);
}
function widget_request_deactivate(widget, args)
{
if (widget.visible)
widget_close(widget, 0);
}
function widget_request_attention(widget, args)
{
if (widget.visible) {
widget_display.removeChildren[0] = widget.widget_control;
widget_display.addChildren[0] = widget.widget_control;
widget.widget_control.flash();
}
}
function widget_request_notification(widget, args)
{
var notif = text_rect('');
notif.children[1].geometry.string[0] = 'Notification from widget';
notif.children[1].geometry.string[1] = ' '+widget.name;
notif.children[1].geometry.string[2] = ' ';
notif.children[1].geometry.string[3] = args[0];
dlg_display.children[0] = notif;
notif.set_size(320, 240);
notif.button_click = function() {
dlg_display.removeChildren[0] = this;
}
}
function widget_place_component(widget, args)
{
var comp = widget.get_component(args[0]);
if (comp==null) {
log(l_err, 'Component '+args[0]+' cannot be found in widget '+widget.name);
return;
}
comp.widget_control.place_x = args[1];
comp.widget_control.place_y = args[2];
comp.widget_control.place_w = args[3];
comp.widget_control.place_h = args[4];
comp.widget_control.place_z = args[5];
comp.widget_control.component_bound = true;
widget.widget_control.refresh_layout(false, comp);
}
function insert_widget_icon(new_wid, no_layout) {
var icon;
icon = icon_button(widget_get_icon(new_wid), new_wid.name, 0);
icon.tooltip = new_wid.name;
new_wid.in_panel = true;
new_wid.visible = false;
new_wid.icon_dock = icon;
icon.button_click = on_widget_launch;
icon.widget = new_wid;
widget_screen.addChildren[0] = new_wid.icon_dock;
if (!no_layout) layout();
}
function scan_directory(dir)
{
var i, j, count, list, new_wid, uri;
list = gpac.enum_directory(dir, '.xml;.wgt;.mgt', 0);
for (i=0; i<list.length; i++) {
uri = list[i].path + list[i].name;
if (list[i].directory) {
scan_directory(uri);
} else {
count = WidgetManager.num_widgets;
for (j=0; j<count; j++) {
var wid = WidgetManager.get(j);
if (wid.url==uri) break;
}
if (j==count) {
new_wid = WidgetManager.open(uri, null);
if (new_wid!=null) {
insert_widget_icon(new_wid, 1);
}
}
}
}
}
function widget_browse()
{
filebrowse = new SFNode('Transform2D');
infobar.set_label('Select widget');
dlg_display.children[0] = filebrowse;
filebrowse.children[0] = icon_button('icons/emblem-unreadable.svg', 'Close', 0);
filebrowse.children[0].button_click = function() {
dlg_display.children.length = 0;
widget_display.scale.x = 1;
layout();
}
filebrowse.children[1] = icon_button('icons/go-previous.svg', 'Previous', 0);
filebrowse.children[1].filebrowse = filebrowse;
filebrowse.children[1].button_click = function () { this.filebrowse.layout(0) };
filebrowse.children[2] = icon_button('icons/go-next.svg', 'Next', 0);
filebrowse.children[2].filebrowse = filebrowse;
filebrowse.children[2].button_click = function () { this.filebrowse.layout(1) };
filebrowse.children[3] = icon_button('icons/go-up.svg', 'Up', 0);
filebrowse.children[3].filebrowse = filebrowse;
filebrowse.children[3].button_click = function () { this.filebrowse.browse(true) };
filebrowse.children[4] = icon_button('icons/Folder.svg', 'Scan Directory', 0);
filebrowse.children[4].filebrowse = filebrowse;
filebrowse.children[4].button_click = function () {
scan_directory(this.filebrowse.directory);
WidgetManager.last_widget_dir = this.filebrowse.directory;
dlg_display.children.length = 0;
widget_display.scale.x = 0;
widget_screen_visible = true;
layout();
}
filebrowse.children[5] = text_label('', 'BEGIN');
filebrowse.set_label = function(label) {
filebrowse.children[5].set_label(label);
}
filebrowse.nb_tools = filebrowse.children.length;
filebrowse.browse = function(go_up) {
this.list = gpac.enum_directory(this.directory, '*.xml;*.wgt;*.mgt', go_up);
if (this.list.length) {
this.directory = this.list[0].path;
this.set_label(this.directory);
} else {
this.set_label('');
}
this.first = 0;
this.layout(0);
}
filebrowse.layout = function(type) {
var w, h, i, y;
this.children.length = this.nb_tools;
this.children[1].hide();
this.children[2].hide();
if (this.directory == '')
this.children[3].hide();
else
this.children[3].show();
if (type==0) {
this.first -= this.nb_items;
if (this.first<0) this.first = 0;
}
else if (type) {
this.first += this.nb_items;
if (this.first + this.nb_items > this.list.length) this.first = this.list.length - this.nb_items;
}
if (this.first) this.children[1].show();
if (this.first+this.nb_items < this.list.length) this.children[2].show();
for (i=0; i<this.nb_items; i++) {
var item;
if (i+this.first>=this.list.length) break;
item = text_rect(this.list[i+this.first].name);
item.path = this.list[i+this.first].path;
item.name = this.list[i+this.first].name;
item.directory = this.list[i+this.first].directory;
item.filebrowse = this;
item.button_click = function() {
if (this.directory) {
this.filebrowse.directory = this.path + this.name;
this.filebrowse.browse(false);
} else {
var value = this.path + this.name;
dlg_display.children.length = 0;
widget_display.scale.x = 1;
widget_screen_visible = true;
layout();
var new_wid = WidgetManager.open(value, null);
if (new_wid==null) return;
WidgetManager.last_widget_dir = this.filebrowse.directory;
insert_widget_icon(new_wid, 0);
}
}
this.children[this.nb_tools+i] = item;
}
this.set_size(this.width, this.height);
}
filebrowse.set_size = function(w, h) {
var i, x, y, isize, nbi;
isize = 24;
if (w>display_width - isize) w = display_width - isize;
this.width = w;
this.height = h;
i = 1;
while ((i+1)*isize <= h - isize) i++;
if (i != this.nb_items) {
this.nb_items = i;
this.layout(0);
return;
}
x = -w/2 + isize/2;
y = h/2 - isize/2;
for (i=0;i<this.nb_tools;i++) {
if (this.nb_tools>i+1) {
this.children[i].set_size(isize, isize);
}
this.children[i].translation.x = x;
this.children[i].translation.y = y;
x += isize;
}
y-=isize;
while (i<this.children.length) {
this.children[i].set_size(w, isize);
this.children[i].translation.x = 0;
this.children[i].translation.y = y;
y-=isize;
i++;
}
}
filebrowse.nb_items = 0;
filebrowse.directory = WidgetManager.last_widget_dir;
filebrowse.browse(0);
widget_display.scale.x = 0;
layout();
}
function onMediaRendererAdd(name, uuid, is_add)
{
var i, count;
count = WidgetManager.num_widgets;
for (i=0; i<count; i++) {
wid = WidgetManager.get(i);
if (wid == null) continue;
if (!wid.widget_control) continue;
wid.widget_control.show_remote();
}
if (upnp_renders) upnp_renders.refresh();
}
function on_upnpopen()
{
upnp_renders = new SFNode('Transform2D');
upnp_renders.nb_items = 0;
upnp_renders.refresh = function () {
var i, count, render, item, start_y, w;
this.children.length = 0;
count = WidgetManager.MPEGUStandardServiceProviders.length;
if (count+1>this.nb_items) count = this.nb_items-1;
item = text_rect('Close');
item.button_click = function() {
dlg_display.children.length = 0;
upnp_renders=null;
widget_display.scale.x = 1;
infobar.set_label('');
}
this.children[this.children.length] = item;
for (i=0; i<count; i++) {
render = WidgetManager.MPEGUStandardServiceProviders[i];
item = text_rect(render.Name);
item.render = render;
item.button_click = function() {
dlg_display.children.length = 0;
upnp_renders=null;
widget_display.scale.x = 1;
infobar.set_label('');
WidgetManager.migrate_widget(this.render, widget_remote_candidate);
widget_close(widget_remote_candidate, 0);
widget_remote_candidate = null;
}
this.children[this.children.length] = item;
}
this.set_size(this.width, this.height);
}
upnp_renders.set_size = function (w, h) {
var i, count, start_y, w;
this.width = w<300 ? w : 300;
this.height = h;
i = 1;
while ((i+1)*icon_size <= h - icon_size) i++;
if (i != this.nb_items) {
this.nb_items = i;
this.refresh();
return;
}
count = this.children.length;
start_y = this.height/2 - icon_size - 4;
for (i=0; i<count; i++) {
this.children[i].set_size(this.width, icon_size);
this.children[i].translation.y = start_y;
start_y-=icon_size+2;
}
}
infobar.set_label('Select remote display');
dlg_display.children[0] = upnp_renders;
widget_display.scale.x = 0;
layout();
}
function onMediaConnect(url, src_ip)
{
if (WidgetManager.probe(url)) {
var new_wid = WidgetManager.open(url, src_ip);
if (new_wid==null) {
return;
}
widget_insert(new_wid);
}
}
// widget get: UI for listWidgets and getWidget
// added by Jean-Claude Dufourd, modeled on filebrowse
function widget_get() {
alert("widget_get");
widgetbrowse = new SFNode('Transform2D');
infobar.set_label('Select widget manager');
dlg_display.children[0] = widgetbrowse;
widgetbrowse.children[0] = icon_button('icons/emblem-unreadable.svg', 'Close', 0);
widgetbrowse.children[0].button_click = function() {
dlg_display.children.length = 0;
widget_display.scale.x = 1;
layout();
};
widgetbrowse.children[1] = text_label('', 'BEGIN');
widgetbrowse.set_label = function(label) {
widgetbrowse.children[1].set_label(label);
};
widgetbrowse.nb_tools = widgetbrowse.children.length;
// this function builds the whole UI the first time
widgetbrowse.layout = function() {
alert("widgetbrowse.layout");
var w, h, i, y;
this.children.length = this.nb_tools;
for (i = 0; i < this.nb_items; i++) {
var item;
if (i >= this.list.length) {
break;
}
item = text_rect(this.list[i].Name);
item.wm = this.list[i];
item.widgetbrowse = this;
item.button_click = function() {
alert("click to select wm: "+this.wm.Name);
this.widgetbrowse.wm = this.wm;
this.wm.standardService.SetActionListener("listWidgets", get_widget_callback(this.wm, this.widgetbrowse), true);
this.wm.standardService.CallAction("listWidgets", new Array());
};
this.children[this.nb_tools + i] = item;
}
this.set_size(this.width, this.height);
};
widgetbrowse.set_size = function(w, h) {
alert("widgetbrowse.set_size "+w+" "+h);
var i, x, y, isize, nbi;
isize = 24;
if (w > display_width - isize) {
w = display_width - isize;
}
this.width = w;
this.height = h;
i = 1;
while ((i + 1) * isize <= h - isize) {
i++;
}
if (i != this.nb_items) {
this.nb_items = i;
this.layout(0);
return;
}
x = -w / 2 + isize / 2;
y = h / 2 - isize / 2;
for (i = 0; i < this.nb_tools; i++) {
if (this.nb_tools > i + 1) {
this.children[i].set_size(isize, isize);
}
this.children[i].translation.x = x;
this.children[i].translation.y = y;
x += isize;
}
y -= isize;
while (i < this.children.length) {
this.children[i].set_size(w, isize);
this.children[i].translation.x = 0;
this.children[i].translation.y = y;
y -= isize;
i++;
}
};
widgetbrowse.nb_items = WidgetManager.MPEGUStandardServiceProviders.length;
widgetbrowse.list = WidgetManager.MPEGUStandardServiceProviders;
widgetbrowse.set_label('Select Widget Manager');
widgetbrowse.layout(0);
widget_display.scale.x = 0;
layout();
}
function get_widget_callback(device, widgetbrowse) {
alert("get_widget_callback "+device.Name+" "+widgetbrowse);
return function() {
// 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("callback |"+act1+"| |"+act2+"|");
widgetbrowse.set_label("Select Widget");
var w, h, i, y;
act1 = act1.split(" ");
act2 = act2.split(" ");
widgetbrowse.children.length = widgetbrowse.nb_tools;
for (i = 0; i < act2.length; i++) {
if (act1[i]=="" || act2[i]=="") continue;
var item = text_rect(act2[i]);
item.widgetCode = act1[i];
item.widgetName = act2[i];
item.widgetbrowse = widgetbrowse;
item.button_click = function() {
alert("selected widget: "+this.widgetName);
dlg_display.children.length = 0;
widget_display.scale.x = 1;
widget_screen_visible = true;
layout();
var arr = new Array();
arr[0] = "widgetCode";
arr[1] = this.widgetCode;
this.widgetbrowse.wm.standardService.SetActionListener("getWidget", get_widget_callback2, true);
this.widgetbrowse.wm.standardService.CallAction("getWidget", arr);
};
widgetbrowse.children[this.nb_tools + i] = item;
}
widgetbrowse.set_size(widgetbrowse.width, widgetbrowse.height);
}
}
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);
}