First iteration of the organize functionality (orginally called bulk

edit).  There is limited functionality in no edits work.  This is
primary a chance for the team to review the ui.  It is in a separate
module to isolate the changes.  Eventually, it will be moved back into core.
This commit is contained in:
Tim Almdal 2009-04-03 00:50:43 +00:00
parent 6883762238
commit f1cb43430b
14 changed files with 630 additions and 0 deletions

View File

@ -0,0 +1,92 @@
<?php defined("SYSPATH") or die("No direct script access.");/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2008 Bharat Mediratta
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class Organize_Controller extends Controller {
private static $_MICRO_THUMB_SIZE = 90;
private static $_MICRO_THUMB_PADDING = 5;
public function index($item_id=1) {
$item = ORM::factory("item", $item_id);
$root = ($item->id == 1) ? $item : ORM::factory("item", 1);
$v = new View("organize.html");
$v->root = $root;
$v->item = $item;
$v->album_tree = $this->tree($item, $root);
$v->edit_form = new View("organize_edit.html");
$v->edit_form->button_pane = new View("organize_button_pane.html");
print $v;
}
public function content($item_id) {
$item = ORM::factory("item", $item_id);
$width = $this->input->get("width");
$height = $this->input->get("height");
$offset = $this->input->get("offset", 0);
$thumbsize = self::$_MICRO_THUMB_SIZE + 2 * self::$_MICRO_THUMB_PADDING;
$page_size = ((int)($width / $thumbsize)) * ceil($height / $thumbsize);
$v = new View("organize_thumb_grid.html");
$v->children = $item->children($page_size, $offset);
$v->thumbsize = self::$_MICRO_THUMB_SIZE;
$v->padding = self::$_MICRO_THUMB_PADDING;
print $v;
}
public function header($item_id) {
$item = ORM::factory("item", $item_id);
print json_encode(array("title" => $item->title,
"description" => empty($item->description) ? "" : $item->description));
}
public function detail($item_id) {
$item = ORM::factory("item", $item_id);
print json_encode(array("title" => $item->title,
"owner" => $item->owner->name,
"date" => date("j-M-Y", $item->updated),
"description" => empty($item->description) ? "" : $item->description));
}
public function tree($item, $parent) {
$albums = ORM::factory("item")
->where(array("parent_id" => $parent->id, "type" => "album"))
->orderby(array("title" => "ASC"))
->find_all();
$v = new View("organize_album.html");
$v->album = $parent;
$v->selected = $parent->id == $item->id;
if ($albums->count()) {
$v->album_icon = $parent->id == 1 || $v->selected ? "ui-icon-minus" : "ui-icon-plus";
} else {
$v->album_icon = "";
}
$v->children = "";
foreach ($albums as $album) {
$v->children .= $this->tree($item, $album);
}
return $v->__toString();
}
}

View File

@ -0,0 +1,98 @@
/* @todo move to theme css */
#gOrganizeTreeContainer,
#gMicroThumbContainer {
overflow-y: auto;
}
#gMicroThumbContainer #gMicroThumbGrid {
margin: 0;
}
#gMicroThumbContainer #gMicroThumbGrid .gMicroThumb {
border: 1px solid #e8e8e8;
border-right-color: #ccc;
border-bottom-color: #ccc;
float: left;
font-size: .7em;
height: 9em;
margin-left: .5em;
margin-top: .5em;
overflow: hidden;
padding: .5em;
text-align: center;
width: 9em;
}
#gOrganizeAlbumDescription {
height: 2em;
overflow-y: auto;
}
#gMicroThumbContainer #gMicroThumbGrid .gAlbum {
background-color: #e8e8e8;
}
#gMicroThumbContainer #gMicroThumbGrid :hover {
background-color: #09F !important;
opacity: .3;
}
.gThumbSelected {
border: 0.2em solid #0099FF !important;
}
.gBranchSelected {
background-color: #6CF !important;
}
.gBranchText {
cursor: pointer;
}
.gBranchCollapsed {
display: none;
}
.gBranchEmpty {
visibility: hidden;
}
#gOrganizeTreeContainer ul ul li {
padding-left: 1.2em;
}
#gOrganizeFormButtons {
bottom: 0.5em;
position: absolute;
}
#gOrganizeFormButtons .submit {
display: inline;
float: none;
left: 0.5em;
position: relative;
}
#gOrganizeFormThumbs {
padding: .5em;
height: 7em;
width: 100%;
overflow: hidden;
}
#gOrganizeFormThumbs div {
margin: 0 auto;
text-align: center;
}
#gOrganizeButtonPane {
padding: .5em;
text-align: center;
}
#gOrganizeFormInfo td {
border: thin none;
padding: 0;
}

View File

@ -0,0 +1,32 @@
<?php defined("SYSPATH") or die("No direct script access.");/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2008 Bharat Mediratta
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class organize_installer {
static function install() {
$version = module::get_version("organize");
if ($version == 0) {
/* @todo Put database creation here */
module::set_version("organize", 1);
}
}
static function uninstall() {
/* @todo Put database table drops here */
module::delete("organize");
}
}

View File

@ -0,0 +1,32 @@
<?php defined("SYSPATH") or die("No direct script access.");/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2008 Bharat Mediratta
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class organize_menu {
static function site($menu, $theme) {
$item = $theme->item();
if ($item && access::can("edit", $item) && $item->is_album()) {
$menu->get("options_menu")
->append(Menu::factory("link")
->id("organize")
->label(t("Organize Album"))
->css_id("gOrganizeLink")
->url(url::site("organize/index/{$item->id}")));
}
}
}

View File

@ -0,0 +1,30 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2008 Bharat Mediratta
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class organize_theme {
static function head($theme) {
// @tdo remove the addition css and organize.js (just here to test)
$script[] = html::script("modules/organize/js/organize_init.js");
$script[] = html::script("modules/organize/js/organize.js");
$script[] = "<link rel=\"stylesheet\" type=\"text/css\" href=\"" .
url::file("modules/organize/css/organize.css") . "\" />";
return implode("\n", $script);
//return html::script("modules/organize/js/organize_init.js");
}
}

View File

@ -0,0 +1,172 @@
/*
* @todo Trap resize of dialog and resize the child areas (tree, grid and edit form)
*/
var url;
var height;
function get_album_content() {
var grid_width = $("#gMicroThumbContainer").width();
url = $("#gMicroThumbContainer").attr("ref");
url = url.replace("__WIDTH__", grid_width);
url = url.replace("__HEIGHT__", height);
retrieve_micro_thumbs(url);
}
function retrieve_micro_thumbs() {
var offset = $("#gMicroThumbGrid li").length;
if (url == null) {
var grid_width = $("#gMicroThumbContainer").width();
url = $("#gMicroThumbContainer").attr("ref");
url = url.replace("__WIDTH__", grid_width);
url = url.replace("__HEIGHT__", height);
}
var url_data = url.replace("__OFFSET__", offset);
url_data = url.replace("__ITEM_ID__", item_id);
$.get(url_data, function(data) {
$("#gMicroThumbGrid").append(data);
get_more_data();
});
}
function get_more_data() {
var element = $("#gMicroThumbContainer").get(0);
var scrollHeight = element.scrollHeight;
var scrollTop = element.scrollTop;
var height = $("#gMicroThumbContainer").height();
var scrollPosition = scrollHeight - (scrollTop + height);
if (scrollPosition > 0 && scrollPosition <= 100) {
retrieve_micro_thumbs();
}
}
function toggle_select(event) {
var clone = null;
var id = $(this).attr("id").replace(/[^0-9]/g, "");
if ($(this).hasClass("gThumbSelected")) {
$(this).removeClass("gThumbSelected");
var newSelect = $(".gThumbSelected");
if (newSelect.size() == 1) {
clone = $(".gThumbSelected").children("img").clone(true);
id = $(".gThumbSelected").attr("id").replace(/[^0-9]/g, "");
} else {
clone = null;
}
} else {
clone = $(this).children("img").clone(true);
$(this).addClass("gThumbSelected");
}
switch ($(".gThumbSelected").size()) {
case 0:
reset_edit_select();
break;
case 1:
$("#gOrganizeFormThumb").empty();
$("#gOrganizeFormThumb").append(clone);
$("#gOrganizeFormNoImage").hide();
$("#gOrganizeFormMultipleImages").hide();
$("#gOrganizeFormThumb").show();
$("#gOrganizeButtonPane").show();
$.getJSON($("#gOrganizeFormInfo").attr("ref").replace("__ITEM_ID__", id), function(data) {
$("#gOrganizeFormTitle").text(data.title);
$("#gOrganizeFormOwner").text(data.owner);
$("#gOrganizeFormDate").text(data.date);
$("#gOrganizeFormDescription").text(data.description);
$("#gOrganizeFormInfo").show();
});
break;
default:
$("#gOrganizeFormThumb").hide();
$("#gOrganizeFormInfo").hide();
$("#gOrganizeFormMultipleImages").show();
}
event.preventDefault();
}
function reset_edit_select() {
$("#gOrganizeFormNoImage").show();
$("#gOrganizeFormThumb").hide();
$("#gOrganizeFormMultipleImages").hide();
$("#gOrganizeButtonPane").hide();
$("#gOrganizeFormInfo").hide();
}
function organize_toggle_children(event) {
var id = $(this).attr("ref");
var span_children = $("#gOrganizeChildren-" + id);
if ($(this).hasClass("ui-icon-plus")) {
$(this).removeClass("ui-icon-plus");
$(this).addClass("ui-icon-minus");
$("#gOrganizeChildren-" + id).removeClass("gBranchCollapsed");
} else {
$(this).removeClass("ui-icon-minus");
$(this).addClass("ui-icon-plus");
$("#gOrganizeChildren-" + id).addClass("gBranchCollapsed");
}
event.preventDefault();
}
function organize_open_folder(event) {
var selected = $(".gBranchSelected");
if ($(selected).attr("id") != $(this).attr("id")) {
$(selected).removeClass("gBranchSelected");
$(this).addClass("gBranchSelected");
item_id = $(this).attr("ref");
$("#gMicroThumbGrid").empty();
var url_header = $("#gDialog #hd").attr("ref").replace("__ITEM_ID__", item_id);
$.getJSON(url_header, function(data) {
$("#gOrganizeAlbumTitle").text(data.title);
$("#gOrganizeAlbumDescription").text(data.description);
});
reset_edit_select();
retrieve_micro_thumbs();
}
event.preventDefault();
}
function organize_dialog_init() {
var size = viewport_size();
height = size.height() - 100;
var width = size.width() - 100;
$("#gDialog").dialog("option", "width", width);
$("#gDialog").dialog("option", "height", height);
$("#gDialog").dialog("open");
if ($("#gDialog h1").length) {
$("#gDialog").dialog('option', 'title', $("#gDialog h1:eq(0)").html());
} else if ($("#gDialog fieldset legend").length) {
$("#gDialog").dialog('option', 'title', $("#gDialog fieldset legend:eq(0)").html());
}
height -= 2 * parseFloat($("#gDialog").css("padding-top"));
height -= 2 * parseFloat($("#gDialog").css("padding-bottom"));
height -= $("#gMicroThumbContainer").position().top;
height -= $("#gDialog #ft").height();
height = Math.round(height);
$("#gMicroThumbContainer").height(height);
$("#gOrganizeTreeContainer").height(height);
$("#gOrganizeEditContainer").height(height);
$(".gOrganizeBranch .ui-icon").click(organize_toggle_children);
$(".gBranchText").click(organize_open_folder);
retrieve_micro_thumbs(item_id);
//showLoading("#gDialog");
}
function viewport_size() {
return {
width : function() {
return window.innerWidth
|| document.documentElement && document.documentElement.clientWidth
|| document.body.clientWidth;
},
height : function() {
return window.innerHeight
|| document.documentElement && document.documentElement.clientHeight
|| document.body.clientHeight;
}
};
}

View File

@ -0,0 +1,24 @@
$("document").ready(function() {
$("#gOrganizeLink").click(function(event) {
event.preventDefault();
var href = event.target.href;
$("body").append('<div id="gDialog"></div>');
$("#gDialog").dialog({
autoOpen: false,
autoResize: false,
modal: true,
resizable: true,
close: closeDialog
});
//showLoading("#gDialog");
$.get(href, function(data) {
$("#gDialog").html(data);
});
return false;
});
});

View File

@ -0,0 +1,3 @@
name = Organize
description = Organize your gallery by apply tags or moving images
version = 1

View File

@ -0,0 +1,43 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<!-- ?= html::script("modules/organize/js/organize.js") ? -->
<script>
var item_id = <?= $item->id ?>;
var csrf = "<?= $csrf ?>";
$("#doc3").ready(function() {
organize_dialog_init();
$("#gMicroThumbContainer").scroll(function() {
get_more_data();
});
});
</script>
<fieldset style="display: none">
<legend><?= t("Organize %name", array("name" => $item->title)) ?></legend>
</fieldset>
<div id="doc3" class="yui-t6">
<div id="hd" ref="<?= url::site("organize/header/__ITEM_ID__") ?>">
<h2 id="gOrganizeAlbumTitle"><?= $item->title ?></h2>
<p id="gOrganizeAlbumDescription"><?= $item->description ?></p>
</div>
<div id="bd">
<div id="yui-main">
<div class="yui-b">
<div class="yui-gf">
<div id="gOrganizeTreeContainer" class="yui-u first" style="border: 1px solid">
<?= $album_tree ?>
</div>
<div id="gMicroThumbContainer" class="yui-u" style="border: 1px solid"
ref="<?= url::site("organize/content/__ITEM_ID__?width=__WIDTH__&height=__HEIGHT__&offset=__OFFSET__") ?>">
<ul id="gMicroThumbGrid">
</ul>
</div>
</div>
</div>
</div>
<div id="gOrganizeEditContainer" class="yui-b" style="border: 1px solid">
<?= $edit_form ?>
</div>
</div>
<div id="ft">
<div class="gProgressBar" style="visibility: hidden" ></div>
</div>
</div>

View File

@ -0,0 +1,15 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<ul>
<li class="gOrganizeBranch ui-icon-left" ref="<?= $album->id ?>">
<span id="gOrganizeIcon-<?= $album->id ?>" ref="<?= $album->id ?>"
class="ui-icon <?= $album_icon ?><? if (empty($album_icon)): ?> gBranchEmpty<? endif ?>">> </span>
<span id="gOrganizeBranch-<?= $album->id ?>" ref="<?= $album->id ?>"
class="<? if ($selected): ?>gBranchSelected <? endif ?>gBranchText">
<?= $album->title ?>
</span>
<span id="gOrganizeChildren-<?= $album->id ?>"
class="<? if ($album_icon == "ui-icon-plus"): ?>gBranchCollapsed<? endif ?>">
<?= $children ?>
<span>
</li>
</ul>

View File

@ -0,0 +1,25 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<? if (graphics::can("rotate")): ?>
<a class="gButtonLink ui-corner-all ui-state-default" href="#" ref="rotate_ccw"
title="<?= t("Rotate 90 degrees counter clockwise") ?>">
<span class="ui-icon ui-icon-rotate-ccw">
<?= t("Rotate 90 degrees counter clockwise") ?>
</span>
</a>
<a class="gButtonLink ui-corner-all ui-state-default" href="#" ref="rotate_cw"
title="<?= t("Rotate 90 degrees clockwise") ?>">
<span class="ui-icon ui-icon-rotate-cw">
<?= t("Rotate 90 degrees clockwise") ?>
</span>
</a>
<? endif ?>
<a class="gButtonLink ui-corner-all ui-state-default" href="#" ref="delete"
title="<?= t("Delete selection") ?>">
<span class="ui-icon ui-icon-trash">
<?= t("Delete selection") ?>
</span>
</a>

View File

@ -0,0 +1,46 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<div id="gOrganizeForm">
<?= form::open(url::site("organize/update/__ITEM_ID__?csrf=__CSRF__&action=__ACTION__"), array("method" => "post")) ?>
<div id="gOrganizeFormThumbs">
<div id="gOrganizeFormNoImage">
<h3 style="text-align:center"><?= t("No Image Selected") ?></h3>
</div>
<div id="gOrganizeFormThumb" style="display: none"></div>
<div id="gOrganizeFormMultipleImages" style="display:none">
<h3 style="text-align:center"><?= t("Multiple Images Selected") ?></h3>
</div>
</div>
<div id="gOrganizeButtonPane" style="display: none">
<?= $button_pane ?>
</div>
<div id="gOrganizeFormInfo" style="display:none"
ref="<?= url::site("organize/detail/__ITEM_ID__") ?>">
<table style="padding: 0;">
<tbody>
<tr>
<td>Title:</td><td><span id="gOrganizeFormTitle"></span></td>
</tr>
<tr>
<td>Owner:</td><td><span id="gOrganizeFormOwner"></span></td>
</tr>
<tr>
<td>Date:</td><td><span id="gOrganizeFormDate"></span></td>
</tr>
<tr>
<td colspan="2">Description:</td>
</tr>
<tr>
<td colspan="2"><span id="gOrganizeFormDescription">&nbsp;</span>
</tr>
</tbody>
</table>
</div>
<span id="gOrganizeFormButtons">
<?= form::submit(array("id" => "gOrganizePauseButton", "name" => "pause", "disabled" => true, "class" => "submit", "style" => "display:none"), t("Pause")) ?>
<?= form::submit(array("id" => "gOrganizeApplyButton", "name" => "apply", "disabled" => true, "class" => "submit"), t("Apply")) ?>
</span>
<?= form::close() ?>
</div>

View File

@ -0,0 +1,14 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<script>
$(".gMicroThumb").click(toggle_select);
</script>
<? foreach ($children as $i => $child): ?>
<? $item_class = "gPhoto"; ?>
<? if ($child->is_album()): ?>
<? $item_class = "gAlbum"; ?>
<? endif ?>
<li id="gMicroThumb-<?= $child->id ?>" class="gMicroThumb <?= $item_class ?>">
<?= $child->micro_thumb_tag(array("class" => "gThumbnail"), $thumbsize) ?>
</li>
<? endforeach ?>

View File

@ -0,0 +1,4 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<? foreach ($children as $i => $child): ?>
<? endforeach ?>