unify map and calendar views as navigation view

This commit is contained in:
rolux 2011-10-03 13:23:11 +00:00
parent 43817ef97c
commit 0cba9842bb
6 changed files with 280 additions and 317 deletions

View file

@ -9,6 +9,7 @@ pandora.ui.clipList = function(videoRatio) {
that = Ox.IconList({ that = Ox.IconList({
fixedRatio: fixedRatio, fixedRatio: fixedRatio,
item: function(data, sort, size) { item: function(data, sort, size) {
Ox.print('*********', data)
size = size || 128; // fixme: is this needed? size = size || 128; // fixme: is this needed?
var ratio, width, height, url, sortKey, info; var ratio, width, height, url, sortKey, info;
if (!ui.item) { if (!ui.item) {

View file

@ -1,4 +1,5 @@
// vim: et:ts=4:sw=4:sts=4:ft=javascript // vim: et:ts=4:sw=4:sts=4:ft=javascript
pandora.ui.item = function() { pandora.ui.item = function() {
var that = Ox.Element(); var that = Ox.Element();
@ -377,7 +378,7 @@ pandora.ui.item = function() {
} else if (pandora.user.ui.itemView == 'map') { } else if (pandora.user.ui.itemView == 'map') {
pandora.$ui.contentPanel.replaceElement(1, pandora.ui.mapView(result.data.videoRatio)); pandora.$ui.contentPanel.replaceElement(1, pandora.ui.navigationView('map', result.data.videoRatio));
} else if (pandora.user.ui.itemView == 'calendar') { } else if (pandora.user.ui.itemView == 'calendar') {
pandora.$ui.contentPanel.replaceElement(1, Ox.Element().html('Calendar')); pandora.$ui.contentPanel.replaceElement(1, Ox.Element().html('Calendar'));

View file

@ -282,93 +282,8 @@ pandora.ui.list = function() {
}, },
width: 512 width: 512
}); });
} else if (view == 'map') { } else if (['map', 'calendar'].indexOf(view) > -1) {
that = pandora.ui.mapView(); that = pandora.ui.navigationView(view);
} else if (view == 'calendar') {
var fixedRatio = 16/9;
that = Ox.SplitPanel({
elements: [
{
element: pandora.$ui.calendar = Ox.Element()
},
{
element: pandora.$ui.clips = Ox.IconList({
fixedRatio: fixedRatio,
item: function(data, sort, size) {
size = size || 128;
var width = data.videoRatio < fixedRatio ? size : size * data.videoRatio / fixedRatio,
height = Math.round(width / data.videoRatio),
itemId = data.id.split('/')[0],
url = '/' + itemId + '/' + height + 'p' + data['in'] + '.jpg';
Ox.print(data.videoRatio, size, fixedRatio, width, height);
return {
height: height,
id: data.id,
info: Ox.formatDuration(data['in'], 'short') + ' - '
+ Ox.formatDuration(data['out'], 'short'),
title: data.value,
url: url,
width: width
};
},
items: [],
keys: ['id', 'value', 'in', 'out', 'videoRatio'],
size: 128,
sort: pandora.user.ui.listSort,
unique: 'id'
}).bindEvent({
open: function(data) {
var id = data.ids[0],
item = pandora.$ui.clips.value(id, 'item'),
points = {
'in': pandora.$ui.clips.value(id, 'in'),
out: pandora.$ui.clips.value(id, 'out')
};
pandora.UI.set('videoPoints.' + item, Ox.extend(points, {
position: points['in']
}));
pandora.UI.set('itemView', 'timeline');
}
}),
id: 'clips',
size: 144 + Ox.UI.SCROLLBAR_SIZE
}
],
orientation: 'horizontal'
})
.bindEvent('resize', function(data) {
});
pandora.api.findEvents({
itemQuery: pandora.user.ui.find,
keys: ['id', 'name', 'start', 'end'],
query: {}
}, function(result) {
that.replaceElement(0, pandora.$ui.calendar = Ox.Calendar({
date: new Date(0),
events: result.data.items,
height: window.innerHeight - pandora.user.ui.showGroups * pandora.user.ui.groupsSize - 61,
range: [-5000, 5000],
width: window.innerWidth - pandora.user.ui.showSidebar * pandora.user.ui.sidebarSize - 2 - 144 - Ox.UI.SCROLLBAR_SIZE,
zoom: 4
}).bindEvent({
select: function(event) {
pandora.$ui.clips.options({
items: function(data, callback) {
return pandora.api.findClips(Ox.extend(data, {
query: {
conditions:[{key: 'event',
value: event.id,
operator:'=='
}]
},
itemQuery: pandora.user.ui.find
}), callback);
}
});
}
}));
});
} else { } else {
// fixme: ??? // fixme: ???
$list = Ox.Element('<div>') $list = Ox.Element('<div>')

View file

@ -1,228 +0,0 @@
// vim: et:ts=4:sw=4:sts=4:ft=javascript
pandora.ui.mapView = function(videoRatio) {
var ui = pandora.user.ui,
listSizes = [
144 + Ox.UI.SCROLLBAR_SIZE,
280 + Ox.UI.SCROLLBAR_SIZE,
416 + Ox.UI.SCROLLBAR_SIZE
],
listSize = listSizes[ui.clipsColumns - 1],
$map = Ox.Map({
find: ui.mapFind,
// 20 menu + 24 toolbar + 1 resizebar + 16 statusbar
height: window.innerHeight - ui.showGroups * ui.groupsSize - 61,
places: function(data, callback) {
var itemQuery;
if (!ui.item) {
itemQuery = ui.find;
} else {
itemQuery = {
conditions: [{key: 'id', value: ui.item, operator: '=='}],
operator: '&'
};
}
return pandora.api.findPlaces(Ox.extend({
itemQuery: itemQuery
}, data), callback);
},
selected: ui.mapSelection,
showTypes: true,
toolbar: true,
width: window.innerWidth - ui.showSidebar * ui.sidebarSize - listSize - 2,
zoombar: true
})
.bindEvent({
resize: function() {
$map.resizeMap();
},
selectplace: function(data) {
var id = data.id || '';
updateToolbar(id ? data : null);
if (id && id[0] != '_') {
$status.html('loading...');
$list.options({
items: function(data, callback) {
var itemQuery;
if (!ui.item) {
itemQuery = ui.find;
} else {
itemQuery = {
conditions: [{key: 'id', value: ui.item, operator: '=='}],
operator: '&'
};
}
return pandora.api.findAnnotations(Ox.extend({
itemQuery: itemQuery,
query: {
conditions: [{key: 'place', value: id, operator:'=='}],
operator: '&'
},
}, data), callback);
}
});
} else {
$list.options({
items: function(data, callback) {
callback({data: {items: data.keys ? [] : 0}});
}
});
}
}
}),
$placeFlag = $('<img>')
.addClass('OxFlag')
.attr({
src: Ox.getImageByGeoname('icon', 16, '')
})
.css({float: 'left', margin: '4px'}),
$placeName = Ox.Label({
textAlign: 'center',
title: '',
width: 96 + Ox.UI.SCROLLBAR_SIZE
})
.css({float: 'left', margin: '4px 0 4px 0'}),
$placeButton = Ox.Button({
title: 'close',
type: 'image'
})
.css({float: 'left', margin: '4px'})
.bindEvent({
click: function() {
$map.options({selected: null});
updateStatusbar(0);
}
}),
$place = $('<div>')
.append($placeFlag)
.append($placeName)
.append($placeButton),
$toolbar = Ox.Bar({size: 24})
.append($place),
$list = pandora.ui.clipList(videoRatio)
.bindEvent({
init: function(data) {
updateStatusbar(data.items);
}
}),
$status = $('<div>')
.css({
width: '100%',
marginTop: '2px',
fontSize: '9px',
textAlign: 'center',
textOverflow: 'ellipsis'
}),
$statusbar = Ox.Bar({size: 16}).append($status),
$listPanel = Ox.SplitPanel({
elements: [
{
element: $toolbar,
size: 24
},
{
element: $list
},
{
element: $statusbar,
size: 16
}
],
orientation: 'vertical'
})
.bindEvent({
resize: function(data) {
resizeToolbar(data.size);
$list.size();
},
resizeend: function(data) {
var size = data.size;
if (listSizes.indexOf(size) == -1) {
if (size <= (listSizes[0] + listSizes[1]) / 2) {
size = listSizes[0];
} else if (size < (listSizes[1] + listSizes[2]) / 2) {
size = listSizes[1];
} else {
size = listSizes[2];
}
that.size(1, size, function() {
$map.resizeMap();
resizeToolbar(size);
// strangely, the animation may still not be fully
// finished, causing the list size to be off by one
setTimeout($list.size, 0);
});
}
pandora.UI.set({clipsColumns: listSizes.indexOf(size) + 1});
}
}),
that = Ox.SplitPanel({
elements: [
{
element: $map,
},
{
element: $listPanel,
resizable: true,
resize: listSizes,
size: listSize,
tooltip: 'clips'
}
],
orientation: 'horizontal'
});
resizeToolbar(listSize);
updateToolbar();
updateStatusbar();
function resizeToolbar(width) {
$placeName.options({width: width - 48});
}
function updateStatusbar(items) {
$status.html(
(items ? Ox.formatNumber(items) : 'No')
+ ' clip' + (items == 1 ? '' : 's')
);
}
function updateToolbar(place) {
$placeFlag.attr({
src: Ox.getImageByGeoname('icon', 16, place ? place.geoname : '')
});
$placeName.options({title: place ? place.name : 'No place'});
$placeButton.options({disabled: !place});
}
that.bindEvent({
pandora_itemsort: function(data) {
ui.item && $list.options({sort: data.value});
},
pandora_listsort: function(data) {
!ui.item && $list.options({sort: data.value});
}
});
pandora.user.ui.mapFind = '';
pandora.user.ui.mapSelection = '';
// fixme: this is needed for some resize handlers further up
pandora.$ui.map = $map;
return that;
};

View file

@ -0,0 +1,274 @@
// vim: et:ts=4:sw=4:sts=4:ft=javascript
pandora.ui.navigationView = function(type, videoRatio) {
var ui = pandora.user.ui,
itemName = type == 'map' ? 'place' : 'event',
listSizes = [
144 + Ox.UI.SCROLLBAR_SIZE,
280 + Ox.UI.SCROLLBAR_SIZE,
416 + Ox.UI.SCROLLBAR_SIZE
],
listSize = listSizes[ui.clipsColumns - 1],
$element = Ox.Element(),
$itemIcon = $('<img>')
.addClass('OxFlag')
.attr({
src: type == 'map'
? Ox.getImageByGeoname('icon', 16, '')
: '/static/png/icon16.png'
})
.css({float: 'left', margin: '4px'}),
$itemLabel = Ox.Label({
textAlign: 'center',
title: '',
width: 96 + Ox.UI.SCROLLBAR_SIZE
})
.css({float: 'left', margin: '4px 0 4px 0'}),
$itemButton = Ox.Button({
title: 'close',
type: 'image'
})
.css({float: 'left', margin: '4px'})
.bindEvent({
click: function() {
$element.options({selected: null});
updateStatusbar(0);
}
}),
$item = $('<div>')
.append($itemIcon)
.append($itemLabel)
.append($itemButton),
$toolbar = Ox.Bar({size: 24})
.append($item),
$list = pandora.ui.clipList(videoRatio)
.bindEvent({
init: function(data) {
updateStatusbar(data.items);
}
}),
$status = $('<div>')
.css({
width: '100%',
marginTop: '2px',
fontSize: '9px',
textAlign: 'center',
textOverflow: 'ellipsis'
}),
$statusbar = Ox.Bar({size: 16}).append($status),
$listPanel = Ox.SplitPanel({
elements: [
{
element: $toolbar,
size: 24
},
{
element: $list
},
{
element: $statusbar,
size: 16
}
],
orientation: 'vertical'
})
.bindEvent({
resize: function(data) {
resizeToolbar(data.size);
$list.size();
},
resizeend: function(data) {
var size = data.size;
if (listSizes.indexOf(size) == -1) {
if (size <= (listSizes[0] + listSizes[1]) / 2) {
size = listSizes[0];
} else if (size < (listSizes[1] + listSizes[2]) / 2) {
size = listSizes[1];
} else {
size = listSizes[2];
}
that.size(1, size, function() {
// strangely, the animation may still not be fully
// finished, causing the list size to be off by one
setTimeout(function() {
$element['resize' + Ox.toTitleCase(type)]();
resizeToolbar(size);
$list.size();
}, 0);
});
}
pandora.UI.set({clipsColumns: listSizes.indexOf(size) + 1});
}
}),
that = Ox.SplitPanel({
elements: [
{
element: $element,
},
{
element: $listPanel,
resizable: true,
resize: listSizes,
size: listSize,
tooltip: 'clips'
}
],
orientation: 'horizontal'
});
if (type == 'map') {
that.replaceElement(0,
$element = Ox.Map({
find: ui.mapFind,
// 20 menu + 24 toolbar + 1 resizebar + 16 statusbar
height: window.innerHeight - ui.showGroups * ui.groupsSize - 61,
places: function(data, callback) {
var itemQuery;
if (!ui.item) {
itemQuery = ui.find;
} else {
itemQuery = {
conditions: [{key: 'id', value: ui.item, operator: '=='}],
operator: '&'
};
}
return pandora.api.findPlaces(Ox.extend({
itemQuery: itemQuery
}, data), callback);
},
selected: ui.mapSelection,
showTypes: true,
toolbar: true,
width: window.innerWidth - ui.showSidebar * ui.sidebarSize - listSize - 2,
zoombar: true
})
.bindEvent({
resize: function() {
$element.resizeMap();
},
selectplace: selectItem
})
);
} else {
pandora.api.findEvents({
itemQuery: ui.find,
keys: ['id', 'name', 'start', 'end'],
query: {}
}, function(result) {
that.replaceElement(0,
$element = Ox.Calendar({
date: new Date(0),
events: result.data.items,
// 20 px menu, 24 px toolbar, 1px resizbar, 16px statusbar
height: window.innerHeight - ui.showGroups * ui.groupsSize - 61,
range: [-5000, 5000],
width: window.innerWidth - ui.showSidebar * ui.sidebarSize - listSize - 2,
zoom: 4
})
.bindEvent({
resize: function(data) {
$element.resizeCalendar();
},
select: selectItem
})
);
});
}
resizeToolbar(listSize);
updateToolbar();
updateStatusbar();
function resizeToolbar(width) {
$itemLabel.options({width: width - 48});
}
function selectItem(data) {
var id = data.id || '';
updateToolbar(id ? data : null);
if (id && id[0] != '_') {
$status.html('loading...');
$list.options({
items: function(data, callback) {
var itemQuery;
if (!ui.item) {
itemQuery = ui.find;
} else {
itemQuery = {
conditions: [{key: 'id', value: ui.item, operator: '=='}],
operator: '&'
};
}
return pandora.api.findClips(Ox.extend({
itemQuery: itemQuery,
query: {
conditions: [{key: itemName, value: id, operator:'=='}],
operator: '&'
},
}, data), callback);
}
});
} else {
$list.options({
items: function(data, callback) {
callback({data: {items: data.keys ? [] : 0}});
}
});
}
}
function updateStatusbar(items) {
$status.html(
(items ? Ox.formatNumber(items) : 'No')
+ ' clip' + (items == 1 ? '' : 's')
);
}
function updateToolbar(item) {
type == 'map' && $itemIcon.attr({
src: Ox.getImageByGeoname('icon', 16, item ? item.geoname : '')
});
$itemLabel.options({
title: item ? item.name : 'No ' + itemName
});
$itemButton.options({disabled: !item});
}
that.bindEvent({
pandora_itemsort: function(data) {
ui.item && $list.options({sort: data.value});
},
pandora_listsort: function(data) {
!ui.item && $list.options({sort: data.value});
}
});
if (type == 'map') {
pandora.user.ui.mapFind = '';
pandora.user.ui.mapSelection = '';
}
// fixme: this is needed for some resize handlers further up
pandora.$ui[type] = $element;
return that;
};

View file

@ -32,9 +32,9 @@
"js/pandora/ui/list.js", "js/pandora/ui/list.js",
"js/pandora/ui/listDialog.js", "js/pandora/ui/listDialog.js",
"js/pandora/ui/mainPanel.js", "js/pandora/ui/mainPanel.js",
"js/pandora/ui/mapView.js",
"js/pandora/ui/mediaView.js", "js/pandora/ui/mediaView.js",
"js/pandora/ui/menu.js", "js/pandora/ui/menu.js",
"js/pandora/ui/navigationView.js",
"js/pandora/ui/orderButton.js", "js/pandora/ui/orderButton.js",
"js/pandora/ui/placesDialog.js", "js/pandora/ui/placesDialog.js",
"js/pandora/ui/preferencesDialog.js", "js/pandora/ui/preferencesDialog.js",