forked from extern/egroupware
* Tile view for filemanager
This commit is contained in:
parent
eb0a91d3fe
commit
33a0d1154a
@ -352,7 +352,7 @@ var et2_dataview_controller = Class.extend({
|
|||||||
if (!_entry.row)
|
if (!_entry.row)
|
||||||
{
|
{
|
||||||
createdRow = true;
|
createdRow = true;
|
||||||
_entry.row = new et2_dataview_row(this._grid);
|
_entry.row = this._createRow(ctx);
|
||||||
_entry.row.setDestroyCallback(this._destroyCallback, ctx);
|
_entry.row.setDestroyCallback(this._destroyCallback, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -388,6 +388,17 @@ var et2_dataview_controller = Class.extend({
|
|||||||
return this.hasData;
|
return this.hasData;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new row.
|
||||||
|
*
|
||||||
|
* @param {type} ctx
|
||||||
|
* @returns {et2_dataview_container}
|
||||||
|
*/
|
||||||
|
_createRow: function(ctx) {
|
||||||
|
return new et2_dataview_row(this._grid);
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function which gets called by the grid when data is requested.
|
* Function which gets called by the grid when data is requested.
|
||||||
*
|
*
|
||||||
|
106
etemplate/js/et2_dataview_view_tile.js
Normal file
106
etemplate/js/et2_dataview_view_tile.js
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
/**
|
||||||
|
* EGroupware eTemplate2 - dataview code
|
||||||
|
*
|
||||||
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||||
|
* @package etemplate
|
||||||
|
* @subpackage dataview
|
||||||
|
* @link http://www.egroupware.org
|
||||||
|
* @author Nathan Gray
|
||||||
|
* @copyright Nathan Gray 2014
|
||||||
|
* @version $Id: et2_dataview_view_container_1.js 46338 2014-03-20 09:40:37Z ralfbecker $
|
||||||
|
*/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/*egw:uses
|
||||||
|
jquery.jquery;
|
||||||
|
et2_dataview_interfaces;
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays tiles or thumbnails (squares) instead of full rows.
|
||||||
|
*
|
||||||
|
* It's important that the template specifies a fixed width and height (via CSS)
|
||||||
|
* so that the rows and columns work out properly.
|
||||||
|
*
|
||||||
|
* @augments et2_dataview_container
|
||||||
|
*/
|
||||||
|
var et2_dataview_tile = et2_dataview_row.extend([],
|
||||||
|
{
|
||||||
|
columns: 4,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the row container. Use the "setRow" function to load the actual
|
||||||
|
* row content.
|
||||||
|
*
|
||||||
|
* @param _parent is the row parent container.
|
||||||
|
* @memberOf et2_dataview_row
|
||||||
|
*/
|
||||||
|
init: function(_parent) {
|
||||||
|
// Call the inherited constructor
|
||||||
|
this._super(_parent);
|
||||||
|
|
||||||
|
// Make sure the needed class is there to get the CSS
|
||||||
|
this.tr.addClass('tile');
|
||||||
|
},
|
||||||
|
|
||||||
|
makeExpandable: function (_expandable, _callback, _context) {
|
||||||
|
// Nope. It mostly works, it's just weird.
|
||||||
|
},
|
||||||
|
|
||||||
|
getAvgHeightData: function() {
|
||||||
|
var res = {
|
||||||
|
"avgHeight": this.getHeight() / this.columns,
|
||||||
|
"avgCount": this.columns
|
||||||
|
};
|
||||||
|
return res;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the height for the tile.
|
||||||
|
*
|
||||||
|
* This is where we do the magic. If a new row should start, we return the proper
|
||||||
|
* height. If this should be another tile in the same row, we say it has 0 height.
|
||||||
|
* @returns {Number}
|
||||||
|
*/
|
||||||
|
getHeight: function() {
|
||||||
|
if(this._index % this.columns == 0)
|
||||||
|
{
|
||||||
|
return this._super();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Broadcasts an invalidation through the container tree. Marks the own
|
||||||
|
* height as invalid.
|
||||||
|
*/
|
||||||
|
invalidate: function() {
|
||||||
|
if(this._inTree && this.tr)
|
||||||
|
{
|
||||||
|
var template_width = $j('.innerContainer',this.tr).children().outerWidth(true);
|
||||||
|
if(template_width)
|
||||||
|
{
|
||||||
|
|
||||||
|
this.tr.css('width', template_width + (this.tr.outerWidth(true) - this.tr.width()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this._recalculate_columns();
|
||||||
|
this._super();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recalculate how many columns we can fit in a row.
|
||||||
|
* While browser takes care of the actual layout, we need this for proper
|
||||||
|
* pagination.
|
||||||
|
*/
|
||||||
|
_recalculate_columns: function() {
|
||||||
|
if(this._inTree && this.tr && this.tr.parent())
|
||||||
|
{
|
||||||
|
this.columns = parseInt(this.tr.parent().innerWidth() / this.tr.outerWidth(true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
@ -138,6 +138,10 @@ var et2_nextmatch = et2_DOMWidget.extend([et2_IResizeable, et2_IInput],
|
|||||||
createNamespace: true,
|
createNamespace: true,
|
||||||
|
|
||||||
columns: [],
|
columns: [],
|
||||||
|
|
||||||
|
// Current view, either row or tile. We store it here as controllers are
|
||||||
|
// recreated when the template changes.
|
||||||
|
view: 'row',
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
@ -1109,6 +1113,9 @@ var et2_nextmatch = et2_DOMWidget.extend([et2_IResizeable, et2_IInput],
|
|||||||
}
|
}
|
||||||
this.controller.setPrefix(this.options.settings.dataStorePrefix);
|
this.controller.setPrefix(this.options.settings.dataStorePrefix);
|
||||||
|
|
||||||
|
// Set the view
|
||||||
|
this.controller._view = this.view;
|
||||||
|
|
||||||
// Load the initial order
|
// Load the initial order
|
||||||
/*this.controller.loadInitialOrder(this._getInitialOrder(
|
/*this.controller.loadInitialOrder(this._getInitialOrder(
|
||||||
this.options.settings.rows, this.options.settings.row_id
|
this.options.settings.rows, this.options.settings.row_id
|
||||||
@ -1651,6 +1658,26 @@ var et2_nextmatch = et2_DOMWidget.extend([et2_IResizeable, et2_IInput],
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Switch view between row and tile.
|
||||||
|
* This should be followed by a call to change the template to match, which
|
||||||
|
* will cause a reload of the grid using the new settings.
|
||||||
|
*
|
||||||
|
* @param {type} view
|
||||||
|
*/
|
||||||
|
set_view: function(view)
|
||||||
|
{
|
||||||
|
// Restrict to the only 2 accepted values
|
||||||
|
if(view == 'tile')
|
||||||
|
{
|
||||||
|
this.view = 'tile';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.view = 'row';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a different / additional handler for dropped files.
|
* Set a different / additional handler for dropped files.
|
||||||
*
|
*
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
et2_dataview_view_row;
|
et2_dataview_view_row;
|
||||||
et2_dataview_controller;
|
et2_dataview_controller;
|
||||||
et2_dataview_interfaces;
|
et2_dataview_interfaces;
|
||||||
|
et2_dataview_view_tile;
|
||||||
|
|
||||||
et2_extension_nextmatch_actions; // Contains nm_action
|
et2_extension_nextmatch_actions; // Contains nm_action
|
||||||
|
|
||||||
@ -30,6 +31,10 @@
|
|||||||
*/
|
*/
|
||||||
var et2_nextmatch_controller = et2_dataview_controller.extend(et2_IDataProvider,
|
var et2_nextmatch_controller = et2_dataview_controller.extend(et2_IDataProvider,
|
||||||
{
|
{
|
||||||
|
// Display constants
|
||||||
|
VIEW_ROW: 'row',
|
||||||
|
VIEW_TILE: 'tile',
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the nextmatch controller.
|
* Initializes the nextmatch controller.
|
||||||
*
|
*
|
||||||
@ -94,6 +99,8 @@ var et2_nextmatch_controller = et2_dataview_controller.extend(et2_IDataProvider,
|
|||||||
// dataUnregisterUID
|
// dataUnregisterUID
|
||||||
this.dataUnregisterUID = _egw.dataUnregisterUID;
|
this.dataUnregisterUID = _egw.dataUnregisterUID;
|
||||||
|
|
||||||
|
// Default to rows
|
||||||
|
this._view = et2_nextmatch_controller.prototype.VIEW_ROW;
|
||||||
},
|
},
|
||||||
|
|
||||||
destroy: function () {
|
destroy: function () {
|
||||||
@ -190,6 +197,34 @@ var et2_nextmatch_controller = et2_dataview_controller.extend(et2_IDataProvider,
|
|||||||
|
|
||||||
/** -- PRIVATE FUNCTIONS -- **/
|
/** -- PRIVATE FUNCTIONS -- **/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new row, either normal or tiled
|
||||||
|
*
|
||||||
|
* @param {type} ctx
|
||||||
|
* @returns {et2_dataview_container}
|
||||||
|
*/
|
||||||
|
_createRow: function(ctx) {
|
||||||
|
switch(this._view)
|
||||||
|
{
|
||||||
|
case et2_nextmatch_controller.prototype.VIEW_TILE:
|
||||||
|
var row = new et2_dataview_tile(this._grid);
|
||||||
|
// Try to overcome chrome rendering issue where float is not
|
||||||
|
// applied properly, leading to incomplete rows
|
||||||
|
window.setTimeout(function() {
|
||||||
|
if(!row.tr) return;
|
||||||
|
row.tr.css('float','none');
|
||||||
|
window.setTimeout(function() {
|
||||||
|
if(!row.tr) return;
|
||||||
|
row.tr.css('float','left');
|
||||||
|
},50);
|
||||||
|
},100);
|
||||||
|
return row;
|
||||||
|
case et2_nextmatch_controller.prototype.VIEW_ROW:
|
||||||
|
default:
|
||||||
|
return new et2_dataview_row(this._grid);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the action and the object manager.
|
* Initializes the action and the object manager.
|
||||||
*/
|
*/
|
||||||
|
@ -1147,6 +1147,18 @@ div.message.floating {
|
|||||||
margin-right: -11px;
|
margin-right: -11px;
|
||||||
}
|
}
|
||||||
/* End of hierarchy */
|
/* End of hierarchy */
|
||||||
|
|
||||||
|
/* Nextmatch tiled view */
|
||||||
|
.et2_nextmatch .egwGridView_grid tr.tile {
|
||||||
|
display: inline-block;
|
||||||
|
width: 240px;
|
||||||
|
float: left;
|
||||||
|
padding: 2px;
|
||||||
|
}
|
||||||
|
.et2_nextmatch .egwGridView_grid tr.tile > td > div > *:first-child {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
/* Mangled link-to widget inside a nextmatch - used for DnD uploads */
|
/* Mangled link-to widget inside a nextmatch - used for DnD uploads */
|
||||||
.et2_nextmatch * .et2_link_to {
|
.et2_nextmatch * .et2_link_to {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
@ -606,6 +606,42 @@ app.classes.filemanager = AppJS.extend(
|
|||||||
this.path_widget[etemplate_name].set_value(_dir);
|
this.path_widget[etemplate_name].set_value(_dir);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggle view between tiles and rows
|
||||||
|
*
|
||||||
|
* @param {string} [view] - Specify what to change the view to. Either 'tile' or 'row'.
|
||||||
|
* @param {et2_widget} [button_widget] - The widget that's calling
|
||||||
|
*/
|
||||||
|
change_view: function(view, button_widget)
|
||||||
|
{
|
||||||
|
var nm = this.et2.getWidgetById('nm');
|
||||||
|
if(!nm)
|
||||||
|
{
|
||||||
|
egw.debug('warn', 'Could not find nextmatch to change view');
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(button_widget && button_widget.instanceOf(et2_button))
|
||||||
|
{
|
||||||
|
// Switch view based on button icon, since controller can get re-created
|
||||||
|
if(typeof view != 'string')
|
||||||
|
{
|
||||||
|
view = button_widget.options.image.replace('list_','');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle button icon to the other view
|
||||||
|
button_widget.set_image("list_"+(view == nm.controller.VIEW_ROW ? nm.controller.VIEW_TILE : nm.controller.VIEW_ROW));
|
||||||
|
|
||||||
|
button_widget.set_label(view == nm.controller.VIEW_ROW ? this.egw.lang("Tile view") : this.egw.lang('List view'));
|
||||||
|
}
|
||||||
|
|
||||||
|
nm.set_view(view);
|
||||||
|
|
||||||
|
// Change template to match
|
||||||
|
this.et2.getWidgetById('nm').set_template(view == nm.controller.VIEW_ROW ? 'filemanager.index.rows' : 'filemanager.tile');
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open/active an item
|
* Open/active an item
|
||||||
*
|
*
|
||||||
|
@ -64,6 +64,32 @@ div.filemanager_navigation > label > input {
|
|||||||
max-height: none;
|
max-height: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tile view
|
||||||
|
table.egwGridView_grid .tile .file_tile {
|
||||||
|
height: 150px;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
.egwGridView_grid .tile span.iconOverlayContainer {
|
||||||
|
display: block;
|
||||||
|
max-width: 140px;
|
||||||
|
}
|
||||||
|
table.egwGridView_grid .tile .file_tile img.vfsMimeIcon {
|
||||||
|
height: auto;
|
||||||
|
width: auto;
|
||||||
|
max-height: 120px;
|
||||||
|
display:block;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
.egwGridView_grid tr.tile:hover .innerContainer {
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
.egwGridView_grid tr.tile:hover .file_tile > :not(.iconOverlayContainer) {
|
||||||
|
position: relative;
|
||||||
|
z-index:90;
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Select file dialog
|
* Select file dialog
|
||||||
*/
|
*/
|
||||||
|
BIN
filemanager/templates/default/images/list_row.png
Normal file
BIN
filemanager/templates/default/images/list_row.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 317 B |
BIN
filemanager/templates/default/images/list_tile.png
Normal file
BIN
filemanager/templates/default/images/list_tile.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 318 B |
@ -50,6 +50,7 @@
|
|||||||
<vfs-name label="Path" id="path" onchange="if(widget.getValue() == '') { app.filemanager.change_dir('~');} return true;" size="80" class="address"/>
|
<vfs-name label="Path" id="path" onchange="if(widget.getValue() == '') { app.filemanager.change_dir('~');} return true;" size="80" class="address"/>
|
||||||
<hbox id="buttons">
|
<hbox id="buttons">
|
||||||
<button label="Go to" id="button[go]" image="key_enter"/>
|
<button label="Go to" id="button[go]" image="key_enter"/>
|
||||||
|
<buttononly label="Tile view" id="button[change_view]" onclick="app.filemanager.change_view" options="list_tile"/>
|
||||||
<image id="tarp" src="buttonseparator"/>
|
<image id="tarp" src="buttonseparator"/>
|
||||||
<buttononly statustext="Rename, change permissions or ownership" label="Edit settings" id="button[edit]" onclick="app.filemanager.editprefs();" options="edit"/>
|
<buttononly statustext="Rename, change permissions or ownership" label="Edit settings" id="button[edit]" onclick="app.filemanager.editprefs();" options="edit"/>
|
||||||
<buttononly label="Create directory" id="button[createdir]" onclick="app.filemanager.createdir();" options="button_createdir,createdir_disabled"/>
|
<buttononly label="Create directory" id="button[createdir]" onclick="app.filemanager.createdir();" options="button_createdir,createdir_disabled"/>
|
||||||
|
30
filemanager/templates/default/tile.xet
Normal file
30
filemanager/templates/default/tile.xet
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- $Id$ -->
|
||||||
|
<overlay>
|
||||||
|
<!--
|
||||||
|
This is used as a tiled template for nextmatch. Note only 1 column, and
|
||||||
|
the vbox has both width and height explicitly defined. These are for the vbox,
|
||||||
|
and any spacing between should be done using its margins.
|
||||||
|
Also important is the tile class on the row, to get the proper display and
|
||||||
|
the column width="100%" to take the whole width
|
||||||
|
-->
|
||||||
|
<template id="filemanager.tile" template="" lang="" group="0" version="1.9.001">
|
||||||
|
<grid width="100%">
|
||||||
|
<columns>
|
||||||
|
<column width="100%"/>
|
||||||
|
</columns>
|
||||||
|
<rows>
|
||||||
|
<row class="th">
|
||||||
|
<nextmatch-header/>
|
||||||
|
</row>
|
||||||
|
<row class="tile $row_cont[class]">
|
||||||
|
<vbox class="file_tile" width="150px" height="150px">
|
||||||
|
<vfs-mime align="center" id="$row"/>
|
||||||
|
<vfs-name id="${row}[name]" no_lang="1" readonly="true"/>
|
||||||
|
<description id="${row}[comment]"/>
|
||||||
|
</vbox>
|
||||||
|
</row>
|
||||||
|
</rows>
|
||||||
|
</grid>
|
||||||
|
</template>
|
||||||
|
</overlay>
|
@ -94,6 +94,31 @@ div.filemanager_navigation > label > input {
|
|||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
max-height: none;
|
max-height: none;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Tile view
|
||||||
|
table.egwGridView_grid .tile .file_tile {
|
||||||
|
height: 150px;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
.egwGridView_grid .tile span.iconOverlayContainer {
|
||||||
|
display: block;
|
||||||
|
max-width: 140px;
|
||||||
|
}
|
||||||
|
table.egwGridView_grid .tile .file_tile img.vfsMimeIcon {
|
||||||
|
height: auto;
|
||||||
|
width: auto;
|
||||||
|
max-height: 120px;
|
||||||
|
display: block;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
.egwGridView_grid tr.tile:hover .innerContainer {
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
.egwGridView_grid tr.tile:hover .file_tile > :not(.iconOverlayContainer) {
|
||||||
|
position: relative;
|
||||||
|
z-index: 90;
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Select file dialog
|
* Select file dialog
|
||||||
*/
|
*/
|
||||||
|
BIN
filemanager/templates/pixelegg/images/list_row.png
Normal file
BIN
filemanager/templates/pixelegg/images/list_row.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
BIN
filemanager/templates/pixelegg/images/list_tile.png
Normal file
BIN
filemanager/templates/pixelegg/images/list_tile.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 996 B |
Loading…
Reference in New Issue
Block a user