From fd089930a1ef4a57d68fd4e8f155e3dc8b06331e Mon Sep 17 00:00:00 2001 From: Chuck Hagenbuch Date: Wed, 3 Dec 2008 22:35:56 -0500 Subject: [PATCH] add drag-n-drop portal code from #6102 --- drag_n_drop_portal/block.php | 37 +++ drag_n_drop_portal/index.php | 69 ++++ drag_n_drop_portal/js/portal.js | 1 + drag_n_drop_portal/js/portal_edit.js | 1 + drag_n_drop_portal/js/src/portal.js | 366 +++++++++++++++++++++ drag_n_drop_portal/js/src/portal_edit.js | 204 ++++++++++++ drag_n_drop_portal/lib/Block/Layout/View/js.php | 113 +++++++ drag_n_drop_portal/params.php | 42 +++ drag_n_drop_portal/save.php | 39 +++ drag_n_drop_portal/select.php | 36 ++ drag_n_drop_portal/templates/portal/params.php | 37 +++ drag_n_drop_portal/themes/graphics/bottom_left.gif | Bin 0 -> 90 bytes .../themes/graphics/bottom_right.gif | Bin 0 -> 339 bytes drag_n_drop_portal/themes/graphics/delete.png | Bin 0 -> 838 bytes drag_n_drop_portal/themes/graphics/edit.png | Bin 0 -> 1204 bytes drag_n_drop_portal/themes/graphics/minus.png | Bin 0 -> 203 bytes drag_n_drop_portal/themes/graphics/plus.png | Bin 0 -> 229 bytes .../themes/graphics/redbox_spinner.gif | Bin 0 -> 6820 bytes drag_n_drop_portal/themes/graphics/reload.png | Bin 0 -> 264 bytes drag_n_drop_portal/themes/graphics/tooltip_bg.png | Bin 0 -> 5545 bytes drag_n_drop_portal/themes/graphics/top_left.gif | Bin 0 -> 190 bytes drag_n_drop_portal/themes/graphics/top_right.gif | Bin 0 -> 1123 bytes drag_n_drop_portal/themes/screen.css | 217 ++++++++++++ 23 files changed, 1162 insertions(+) create mode 100644 drag_n_drop_portal/block.php create mode 100644 drag_n_drop_portal/index.php create mode 100644 drag_n_drop_portal/js/portal.js create mode 100644 drag_n_drop_portal/js/portal_edit.js create mode 100644 drag_n_drop_portal/js/src/portal.js create mode 100644 drag_n_drop_portal/js/src/portal_edit.js create mode 100644 drag_n_drop_portal/lib/Block/Layout/View/js.php create mode 100644 drag_n_drop_portal/params.php create mode 100644 drag_n_drop_portal/save.php create mode 100644 drag_n_drop_portal/select.php create mode 100644 drag_n_drop_portal/templates/portal/params.php create mode 100644 drag_n_drop_portal/themes/graphics/bottom_left.gif create mode 100644 drag_n_drop_portal/themes/graphics/bottom_right.gif create mode 100644 drag_n_drop_portal/themes/graphics/delete.png create mode 100644 drag_n_drop_portal/themes/graphics/edit.png create mode 100644 drag_n_drop_portal/themes/graphics/minus.png create mode 100644 drag_n_drop_portal/themes/graphics/plus.png create mode 100644 drag_n_drop_portal/themes/graphics/redbox_spinner.gif create mode 100644 drag_n_drop_portal/themes/graphics/reload.png create mode 100644 drag_n_drop_portal/themes/graphics/tooltip_bg.png create mode 100644 drag_n_drop_portal/themes/graphics/top_left.gif create mode 100644 drag_n_drop_portal/themes/graphics/top_right.gif create mode 100644 drag_n_drop_portal/themes/screen.css diff --git a/drag_n_drop_portal/block.php b/drag_n_drop_portal/block.php new file mode 100644 index 000000000..d105d908d --- /dev/null +++ b/drag_n_drop_portal/block.php @@ -0,0 +1,37 @@ + + * @package Folks + */ +define('HORDE_BASE', dirname(__FILE__) . '/..'); +require_once HORDE_BASE . '/lib/base.php'; +require_once 'Horde/Loader.php'; + +// Block to load +$block_id = Util::getFormData('block'); +list($app, $name) = explode(':', $block_id); + +$block_data = array(); +$block = Horde_Block_Collection::getBlock($app, $name, Util::getFormData('defaults')); +if ($block instanceof PEAR_Error) { + $block_data['title'] = $block->getMessage(); + $block_data['content'] = $block->getDebugInfo(); +} else { + $block_data['title'] = @$block->getTitle(); + if ($block_data['title'] instanceof PEAR_Error) { + $block_data['title'] = $block_data['title']->getMessage(); + } + $block_data['content'] = @$block->getContent(); + if ($block_data['content'] instanceof PEAR_Error) { + $block_data['content'] = $block_data['content']->getDebugInfo(); + } +} + +echo Horde_Serialize::serialize($block_data, SERIALIZE_JSON, NLS::getCharset()); diff --git a/drag_n_drop_portal/index.php b/drag_n_drop_portal/index.php new file mode 100644 index 000000000..7bfb3def6 --- /dev/null +++ b/drag_n_drop_portal/index.php @@ -0,0 +1,69 @@ + + * @package Folks + */ +define('HORDE_BASE', dirname(__FILE__) . '/..'); +require_once HORDE_BASE . '/lib/base.php'; +require_once 'Horde/Loader.php'; +require_once './lib/Block/Layout/View/js.php'; + +if (!Auth::isAuthenticated()) { + Horde::authenticationFailureRedirect(); +} + +// Load layout from preferences. +$layout_pref = unserialize($prefs->getValue('portal_layout')); +if (!is_array($layout_pref)) { + $layout_pref = array(); +} +if (!count($layout_pref)) { + $layout_pref = Horde_Block_Collection::getFixedBlocks(); +} + +// Render layout. +$view = new Horde_Block_Layout_View_Js($layout_pref); +$layout_html = $view->toHtml(); + +$title = _("Edit yout profile page"); + +Horde::addScriptFile('prototype.js', 'horde', true); +Horde::addScriptFile('effects.js', 'horde', true); +Horde::addScriptFile('redbox.js', 'horde', true); +require HORDE_TEMPLATES . '/common-header.inc'; +require HORDE_TEMPLATES . '/menu/menu.inc'; +?> + + + + + + + + + + +
+ + +get('templates', 'horde') . '/common-footer.inc'; diff --git a/drag_n_drop_portal/js/portal.js b/drag_n_drop_portal/js/portal.js new file mode 100644 index 000000000..2cc5e9456 --- /dev/null +++ b/drag_n_drop_portal/js/portal.js @@ -0,0 +1 @@ +if(typeof Draggable=="undefined"){throw("widget.js requires including script.aculo.us' dragdrop.js library")}if(typeof Builder=="undefined"){throw("widget.js requires including script.aculo.us' builder.js library")}if(typeof Xilinus=="undefined"){Xilinus={}}Builder.dump();Xilinus.Widget=Class.create();Xilinus.Widget.lastId=0;Xilinus.Widget.remove=function(B,A){if(A&&A.afterFinish){A.afterFinish.call()}};Object.extend(Xilinus.Widget.prototype,{initialize:function(D,E){D=D||"widget";this._id=E||("widget_"+Xilinus.Widget.lastId++);this._titleDiv=DIV({className:"header",id:this._getId("header")},"");this._contentDiv=DIV({className:"headerbox",id:this._getId("content")},"");this._footerDiv=DIV({className:D+"_statusbar",id:this._getId("footer")},"");var C=DIV({className:"header"},this._titleDiv);var B=DIV({className:"headerbox"},this._contentDiv);var A=DIV({className:D+"_sw"},this._footerDiv);this._div=DIV({className:D+(D!="widget"?" widget":""),id:this._getId()},[C,B,A]);this._div.widget=this;return this},destroy:function(){this._div.remove()},getElement:function(){return $(this._getId())||$(this._div)},setTitle:function(A){$(this._titleDiv).update(A);return this},getTitle:function(A){return $(this._titleDiv)},setFooter:function(A){$(this._footerDiv).update(A);return this},getFooter:function(A){return $(this._footerDiv)},setContent:function(A){$(this._contentDiv).update(A);return this},getContent:function(A){return $(this._contentDiv)},updateHeight:function(){$(this._contentDiv).setStyle({height:null});var A=$(this._contentDiv).getHeight();$(this._contentDiv).setStyle({height:A+"px"})},_getId:function(A){return(A?A+"_":"")+this._id}});Xilinus.Portal=Class.create();Object.extend(Xilinus.Portal.prototype,{lastEvent:null,widgets:null,columns:null,initialize:function(B,A){this.options=Object.extend({url:null,onOverWidget:null,onOutWidget:null,onChange:null,onUpdate:null,removeEffect:Xilinus.Widget.remove},A);this._columns=(typeof B=="string")?$$(B):B;this._widgets=new Array();this._columns.each(function(C){Droppables.add(C,{onHover:this.onHover.bind(this),overlap:"vertical",accept:this.options.accept})}.bind(this));this._outTimer=null;this._columns.invoke("undoPositioned");this._currentOverWidget=null;this._widgetMouseOver=this.widgetMouseOver.bindAsEventListener(this);this._widgetMouseOut=this.widgetMouseOut.bindAsEventListener(this);Draggables.addObserver({onEnd:this.endDrag.bind(this),onStart:this.startDrag.bind(this)})},add:function(C,B,A){A=typeof A=="undefined"?true:A;this._widgets.push(C);if(this.options.accept){C.getElement().addClassName(this.options.accept)}this._columns[B].appendChild(C.getElement());C.updateHeight();if(A){C.draggable=new Draggable(C.getElement(),{handle:C._titleDiv,revert:false});C.getTitle().addClassName("widget_draggable")}this._updateColumnsHeight();if(this.options.onOverWidget){C.getElement().immediateDescendants().invoke("observe","mouseover",this._widgetMouseOver)}if(this.options.onOutWidget){C.getElement().immediateDescendants().invoke("observe","mouseout",this._widgetMouseOut)}},remove:function(A){this._widgets.reject(function(B){return B==A});if(this.options.onOverWidget){A.getElement().immediateDescendants().invoke("stopObserving","mouseover",this._widgetMouseOver)}if(this.options.onOutWidget){A.getElement().immediateDescendants().invoke("stopObserving","mouseout",this._widgetMouseOut)}if(A.draggable){A.draggable.destroy()}this.options.removeEffect(A.getElement(),{afterFinish:function(){A.destroy()}});this._updateColumnsHeight()},serialize:function(){parameters="";this._columns.each(function(A){var B=A.immediateDescendants().collect(function(C){return A.id+"[]="+C.id}).join("&");parameters+=B+"&"});return parameters},addWidgetControls:function(A){$(A).observe("mouseover",this._widgetMouseOver);$(A).observe("mouseout",this._widgetMouseOut)},widgetMouseOver:function(B){this._clearTimer();var A=Event.element(B).up(".widget");if(this._currentOverWidget==null||this._currentOverWidget!=A){if(this._currentOverWidget&&this._currentOverWidget!=A){this.options.onOutWidget(this,this._currentOverWidget.widget)}this._currentOverWidget=A;this.options.onOverWidget(this,A.widget)}},widgetMouseOut:function(B){this._clearTimer();var A=Event.element(B).up(".widget");this._outTimer=setTimeout(this._doWidgetMouseOut.bind(this,A),100)},_doWidgetMouseOut:function(A){this._currentOverWidget=null;this.options.onOutWidget(this,A.widget)},startDrag:function(B,A){var D=A.element;if(!this._widgets.find(function(F){return F==D.widget})){return}var C=D.parentNode;var E=DIV({className:"widget_ghost"},"");$(E).setStyle({height:D.getHeight()+"px"});C.insertBefore(E,D);D.setStyle({width:D.getWidth()+"px"});Position.absolutize(D);document.body.appendChild(D);A.element.ghost=E;this._savePosition=this.serialize()},endDrag:function(B,A){var D=A.element;if(!this._widgets.find(function(E){return E==D.widget})){return}var C=D.ghost.parentNode;C.insertBefore(A.element,D.ghost);D.ghost.remove();if(Prototype.Browser.Opera){D.setStyle({top:0,left:0,width:"100%",height:D._originalHeight,zIndex:null,opacity:null,position:"relative"})}else{D.setStyle({top:null,left:null,width:null,height:D._originalHeight,zIndex:null,opacity:null,position:"relative"})}D.ghost=null;D.widget.updateHeight();this._updateColumnsHeight();if(this._savePosition!=this.serialize()){if(this.options.url){new Ajax.Request(this.options.url,{parameters:this.serialize()})}if(this.options.onUpdate){this.options.onUpdate(this)}}},onHover:function(D,H,I){var A=Position.cumulativeOffset(H);var J=A[0]+10;var F=A[1]+(1-I)*H.getHeight();if(Position.within(D.ghost,J,F)){return}var M=false;var G=false;for(var C=0,B=this._widgets.length;CE&&L!=D.ghost){H.appendChild(D.ghost);G=true}}}if(G&&this.options.onChange){this.options.onChange(this)}this._updateColumnsHeight()},_updateColumnsHeight:function(){var A=0;this._columns.each(function(B){A=Math.max(A,B.immediateDescendants().inject(0,function(D,C){return D+C.getHeight()}))});this._columns.invoke("setStyle",{height:A+"px"})},_clearTimer:function(){if(this._outTimer){clearTimeout(this._outTimer);this._outTimer=null}}}); \ No newline at end of file diff --git a/drag_n_drop_portal/js/portal_edit.js b/drag_n_drop_portal/js/portal_edit.js new file mode 100644 index 000000000..03f7f3bf6 --- /dev/null +++ b/drag_n_drop_portal/js/portal_edit.js @@ -0,0 +1 @@ +var _widgets_blocks=new Array();var _layout_params=new Array();function onOverWidget(A,B){B.getElement().insertBefore($("control_buttons"),B.getElement().firstChild);$("control_buttons").show()}function onOutWidget(A,B){$("control_buttons").hide()}function minimizeWidget(A){var B=$(A).up(".widget").widget;id=B._getId().substr(7);if($("content_widget_"+id).style.display=="none"){$("content_widget_"+id).style.display="block";A.id="minimize_button"}else{$("content_widget_"+id).style.display="none";A.id="maximize_button"}}function removeWidget(A){var B=$(A).up(".widget").widget;if(confirm(confirm_remove)){document.body.appendChild($("control_buttons").hide());portal.remove(B)}}function listWidgets(){RedBox.loading();new Ajax.Request(list_url,{method:"get",onSuccess:function(A){RedBox.showHtml('
'+A.responseText+"
")},onFailure:function(A){RedBox.close()}})}function addWidget(){select=$("block_selection");title=select.options[select.selectedIndex].text;widget=new Xilinus.Widget();widget.setTitle(title);widget.setContent(title);portal.add(widget,parseInt($F("block_column")));_widgets_blocks[_widgets_blocks.length]=select.value;_layout_params[_widgets_blocks.length]=new Array();editWidget(widget);cancelRedBox()}function reloadWidget(A){if($(A).id=="reload_button"){var B=$(A).up(".widget").widget}else{var B=A}var C=B._getId().substr(7);new Ajax.Request(load_url,{parameters:getAjaxParameters(A),method:"get",onSuccess:function(D){block_data=D.responseText.evalJSON(true);B.setTitle(block_data.title);B.setContent(block_data.content);_widgets_blocks[B._getId().substr(7)]=block_used},onFailure:function(D){alert("Someting gone wrong.")}})}function editWidget(A){if($(A).id=="reload_button"){var B=$(A).up(".widget").widget}else{var B=A}new Ajax.Request(edit_url,{parameters:getAjaxParameters(A),method:"get",onSuccess:function(C){RedBox.showHtml('
'+C.responseText+"
")},onFailure:function(C){RedBox.close()}})}function getAjaxParameters(A){if($(A).id=="reload_button"||$(A).id=="edit_button"){var B=$(A).up(".widget").widget}else{var B=A}var C=B._getId().substr(7);parameters="block="+_widgets_blocks[C];parameters=parameters+"&widget="+B._getId();p=_layout_params[C];for(a in p){if(typeof(p[a])!="string"){break}parameters=parameters+"&defaults["+a+"]="+p[a]}return parameters}function setParams(){widget_name="";params=new Array();inputs=$("blockform").getElements();inputs.each(function(B){name=B.name.substr(0,6);if(name=="params"){pos=B.name.indexOf("]",7);param_name=B.name.substr(7,pos-7);if(B.type=="checkbox"){params[param_name]=B.checked}else{params[param_name]=B.value}}if(name=="widget"){widget_name=B.value}});_layout_params[widget_name.substr(7)]=params;var A=$(widget_name).widget;reloadWidget(A);cancelRedBox()}function noParams(B,C){var A=$(B).widget;reloadWidget(A);cancelRedBox()}function cancelRedBox(){RedBox.close();return false}function savePortal(){parameters=portal.serialize();for(var A=0;A<_layout_params.length;A++){parameters=parameters+"¶ms["+A+"][type]="+_widgets_blocks[A];p=_layout_params[A];for(a in p){if(typeof(p[a])!="string"){break}parameters=parameters+"¶ms["+A+"]["+a+"]="+p[a]}}new Ajax.Request(save_url,{parameters:parameters,method:"post"})}; \ No newline at end of file diff --git a/drag_n_drop_portal/js/src/portal.js b/drag_n_drop_portal/js/src/portal.js new file mode 100644 index 000000000..a22b33bfd --- /dev/null +++ b/drag_n_drop_portal/js/src/portal.js @@ -0,0 +1,366 @@ +// Copyright (c) 2006 Sébastien Gruhier (http://xilinus.com, http://itseb.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// VERSION 1.1-trunk + +if(typeof Draggable == 'undefined') + throw("widget.js requires including script.aculo.us' dragdrop.js library"); + +if(typeof Builder == 'undefined') + throw("widget.js requires including script.aculo.us' builder.js library"); + +// Xilinus namespace +if(typeof Xilinus == 'undefined') + Xilinus = {} + +Builder.dump(); + + +Xilinus.Widget = Class.create(); +Xilinus.Widget.lastId = 0; +Xilinus.Widget.remove = function(element, options) { + if (options && options.afterFinish) + options.afterFinish.call(); +} + +Object.extend(Xilinus.Widget.prototype, { + initialize: function(className, id) { + className = className || "widget"; + this._id = id || ("widget_" + Xilinus.Widget.lastId++); + + this._titleDiv = DIV({className: 'header', id: this._getId("header")}, ""); + this._contentDiv = DIV({className: 'headerbox', id: this._getId("content")}, ""); + this._footerDiv = DIV({className: className + '_statusbar', id: this._getId("footer")}, ""); + + var divHeader = DIV({className: 'header' }, this._titleDiv); + var divContent = DIV({className: 'headerbox' }, this._contentDiv); + var divFooter = DIV({className: className + '_sw' }, this._footerDiv); + + this._div = DIV({className: className + (className != "widget" ? " widget" : ""), id: this._getId()}, [divHeader, divContent, divFooter]); + this._div.widget = this; + + return this; + }, + + destroy: function() { + this._div.remove(); + }, + + getElement: function() { + return $(this._getId()) || $(this._div); + }, + + setTitle: function(title) { + $(this._titleDiv).update(title); + return this; + }, + + getTitle: function(title) { + return $(this._titleDiv) + }, + + setFooter: function(title) { + $(this._footerDiv).update(title); + return this; + }, + + getFooter: function(title) { + return $(this._footerDiv) + }, + + setContent: function(title) { + $(this._contentDiv).update(title); + return this; + }, + + getContent: function(title) { + return $(this._contentDiv) + }, + + updateHeight: function() { + $(this._contentDiv).setStyle({height: null}) + + var h = $(this._contentDiv).getHeight(); + $(this._contentDiv).setStyle({height: h + "px"}) + }, + + // PRIVATE FUNCTIONS + _getId: function(prefix) { + return (prefix ? prefix + "_" : "") + this._id; + } +}); + + +Xilinus.Portal = Class.create() +Object.extend(Xilinus.Portal.prototype, { + lastEvent: null, + widgets: null, + columns: null, + + initialize: function(columns, options) { + this.options = Object.extend({ + url: null, // Url called by Ajax.Request after a drop + onOverWidget: null, // Called when the mouse goes over a widget + onOutWidget: null, // Called when the mouse goes out of a widget + onChange: null, // Called a widget has been move during drag and drop + onUpdate: null, // Called a widget has been move after drag and drop + removeEffect: Xilinus.Widget.remove // Remove effect (by default no effect), you can set it to Effect.SwitchOff for example + }, options) + this._columns = (typeof columns == "string") ? $$(columns) : columns; + this._widgets = new Array(); + this._columns.each(function(element) {Droppables.add(element, {onHover: this.onHover.bind(this), + overlap: "vertical", + accept: this.options.accept})}.bind(this)); + this._outTimer = null; + + // Draggable calls makePositioned for IE fix (??), I had to remove it for all browsers fix :) to handle properly zIndex + this._columns.invoke("undoPositioned"); + + this._currentOverWidget = null; + this._widgetMouseOver = this.widgetMouseOver.bindAsEventListener(this); + this._widgetMouseOut = this.widgetMouseOut.bindAsEventListener(this); + + Draggables.addObserver({ onEnd: this.endDrag.bind(this), onStart: this.startDrag.bind(this) }); + }, + + add: function(widget, columnIndex, draggable) { + draggable = typeof draggable == "undefined" ? true : draggable + // Add to widgets list + this._widgets.push(widget); + if (this.options.accept) + widget.getElement().addClassName(this.options.accept) + // Add element to column + this._columns[columnIndex].appendChild(widget.getElement()); + widget.updateHeight(); + + // Make header draggable + if (draggable) { + widget.draggable = new Draggable(widget.getElement(),{ handle: widget._titleDiv, revert: false}); + widget.getTitle().addClassName("widget_draggable"); + } + + // Update columns heights + this._updateColumnsHeight(); + + // Add mouse observers + if (this.options.onOverWidget) + widget.getElement().immediateDescendants().invoke("observe", "mouseover", this._widgetMouseOver); + if (this.options.onOutWidget) + widget.getElement().immediateDescendants().invoke("observe", "mouseout", this._widgetMouseOut); + }, + + remove: function(widget) { + // Remove from the list + this._widgets.reject(function(w) { return w == widget}); + + // Remove observers + if (this.options.onOverWidget) + widget.getElement().immediateDescendants().invoke("stopObserving", "mouseover", this._widgetMouseOver); + if (this.options.onOutWidget) + widget.getElement().immediateDescendants().invoke("stopObserving", "mouseout", this._widgetMouseOut); + + // Remove draggable + if (widget.draggable) + widget.draggable.destroy(); + + // Remove from the dom + this.options.removeEffect(widget.getElement(), {afterFinish: function() {widget.destroy();}}); + + // Update columns heights + this._updateColumnsHeight(); + }, + + serialize: function() { + parameters = "" + this._columns.each(function(column) { + var p = column.immediateDescendants().collect(function(element) { + return column.id + "[]=" + element.id + }).join("&") + parameters += p + "&" + }); + + return parameters; + }, + + addWidgetControls: function(element) { + $(element).observe("mouseover", this._widgetMouseOver); + $(element).observe("mouseout", this._widgetMouseOut); + }, + + // EVENTS CALLBACKS + widgetMouseOver: function(event) { + this._clearTimer(); + + var element = Event.element(event).up(".widget"); + if (this._currentOverWidget == null || this._currentOverWidget != element) { + if (this._currentOverWidget && this._currentOverWidget != element) + this.options.onOutWidget(this, this._currentOverWidget.widget) + + this._currentOverWidget = element; + this.options.onOverWidget(this, element.widget) + } + }, + + widgetMouseOut: function(event) { + this._clearTimer(); + var element = Event.element(event).up(".widget"); + this._outTimer = setTimeout(this._doWidgetMouseOut.bind(this, element), 100); + }, + + _doWidgetMouseOut: function(element) { + this._currentOverWidget = null; + this.options.onOutWidget(this, element.widget) + }, + + // DRAGGABLE OBSERVER CALLBACKS + startDrag: function(eventName, draggable) { + var widget = draggable.element; + + if (!this._widgets.find(function(w) {return w == widget.widget})) + return; + + var column = widget.parentNode; + + // Create and insert ghost widget + var ghost = DIV({className: 'widget_ghost'}, ""); + $(ghost).setStyle({height: widget.getHeight() + 'px'}) + + column.insertBefore(ghost, widget); + + // IE Does not absolutize properly the widget, needs to set width before + widget.setStyle({width: widget.getWidth() + "px"}); + + // Absolutize and move widget on body + Position.absolutize(widget); + document.body.appendChild(widget); + + // Store ghost to drag widget for later use + draggable.element.ghost = ghost; + + // Store current position + this._savePosition = this.serialize(); + }, + + endDrag: function(eventName, draggable) { + var widget = draggable.element; + if (!this._widgets.find(function(w) {return w == widget.widget})) + return; + + var column = widget.ghost.parentNode; + + column.insertBefore(draggable.element, widget.ghost); + widget.ghost.remove(); + + if (Prototype.Browser.Opera) + widget.setStyle({top: 0, left: 0, width: "100%", height: widget._originalHeight, zIndex: null, opacity: null, position: "relative"}) + else + widget.setStyle({top: null, left: null, width: null, height: widget._originalHeight, zIndex: null, opacity: null, position: "relative"}) + + widget.ghost = null; + widget.widget.updateHeight(); + this._updateColumnsHeight(); + + // Fire events if changed + if (this._savePosition != this.serialize()) { + if (this.options.url) + new Ajax.Request(this.options.url, {parameters: this.serialize()}); + + if (this.options.onUpdate) + this.options.onUpdate(this); + } + }, + + onHover: function(dragWidget, dropon, overlap) { + var offset = Position.cumulativeOffset(dropon); + var x = offset[0] + 10; + var y = offset[1] + (1 - overlap) * dropon.getHeight(); + + // Check over ghost widget + if (Position.within(dragWidget.ghost, x, y)) + return; + + // Find if it's overlapping a widget + var found = false; + var moved = false; + for (var index = 0, len = this._widgets.length; index < len; ++index) { + var w = this._widgets[index].getElement(); + if (w == dragWidget || w.parentNode != dropon) + continue; + + if (Position.within(w, x, y)) { + var overlap = Position.overlap( 'vertical', w); + // Bottom of the widget + if (overlap < 0.5) { + // Check if the ghost widget is not already below this widget + if (w.next() != dragWidget.ghost) { + w.parentNode.insertBefore(dragWidget.ghost, w.next()); + moved = true; + } + } + // Top of the widget + else { + // Check if the ghost widget is not already above this widget + if (w.previous() != dragWidget.ghost) { + w.parentNode.insertBefore(dragWidget.ghost, w); + moved = true; + } + } + found = true; + break; + } + } + // Not found a widget + if (! found) { + // Check if dropon has ghost widget + if (dragWidget.ghost.parentNode != dropon) { + // Get last widget bottom value + var last = dropon.immediateDescendants().last(); + var yLast = last ? Position.cumulativeOffset(last)[1] + last.getHeight() : 0; + if (y > yLast && last != dragWidget.ghost) { + dropon.appendChild(dragWidget.ghost); + moved = true; + } + } + } + if (moved && this.options.onChange) + this.options.onChange(this) + + this._updateColumnsHeight(); + }, + + // PRIVATE FUNCTIONS + _updateColumnsHeight: function() { + var h = 0; + this._columns.each(function(col) { + h = Math.max(h, col.immediateDescendants().inject(0, function(sum, element) { + return sum + element.getHeight(); + })); + }) + this._columns.invoke("setStyle", {height: h + 'px'}) + }, + + _clearTimer: function() { + if (this._outTimer) { + clearTimeout(this._outTimer); + this._outTimer = null; + } + } +}); diff --git a/drag_n_drop_portal/js/src/portal_edit.js b/drag_n_drop_portal/js/src/portal_edit.js new file mode 100644 index 000000000..f664f2fe0 --- /dev/null +++ b/drag_n_drop_portal/js/src/portal_edit.js @@ -0,0 +1,204 @@ + +var _widgets_blocks = new Array(); +var _layout_params = new Array(); + +function onOverWidget(portal, widget) { + widget.getElement().insertBefore($('control_buttons'), widget.getElement().firstChild); + $('control_buttons').show(); +} + +function onOutWidget(portal, widget) { + $('control_buttons').hide(); +} + +function minimizeWidget(element) { + var widget = $(element).up(".widget").widget; + id = widget._getId().substr(7); + if ($('content_widget_' + id).style.display == 'none') { + $('content_widget_' + id).style.display = 'block'; + element.id = 'minimize_button'; + } else { + $('content_widget_' + id).style.display = 'none'; + element.id = 'maximize_button'; + } +} + +function removeWidget(element) { + var widget = $(element).up(".widget").widget; + + if (confirm(confirm_remove)) { + document.body.appendChild($('control_buttons').hide()) + portal.remove(widget); + } +} + +function listWidgets() { + + RedBox.loading(); + + // load edit options + new Ajax.Request(list_url, { + method: 'get', + onSuccess: function(transport) { + RedBox.showHtml('
' + transport.responseText + '
'); + }, + onFailure: function(transport) { + RedBox.close(); + } + }); +} + +function addWidget() { + + // Add widget + select = $('block_selection'); + title = select.options[select.selectedIndex].text; + + widget = new Xilinus.Widget(); + widget.setTitle(title); + widget.setContent(title); + portal.add(widget, parseInt($F('block_column'))); + + _widgets_blocks[_widgets_blocks.length] = select.value; + _layout_params[_widgets_blocks.length] = new Array(); + + // Edit wiget + editWidget(widget); + + cancelRedBox(); +} + +function reloadWidget(element) { + + if ($(element).id == 'reload_button') { + var widget = $(element).up(".widget").widget; + } else { + var widget = element; + } + + var id = widget._getId().substr(7); + + new Ajax.Request(load_url, { + parameters: getAjaxParameters(element), + method: 'get', + onSuccess: function(transport) { + block_data = transport.responseText.evalJSON(true); + widget.setTitle(block_data['title']); + widget.setContent(block_data['content']); + _widgets_blocks[widget._getId().substr(7)] = block_used; + }, + onFailure: function(transport) { + alert('Someting gone wrong.'); + } + }); +} + +function editWidget(element) { + + if ($(element).id == 'reload_button') { + var widget = $(element).up(".widget").widget; + } else { + var widget = element; + } + + new Ajax.Request(edit_url, { + parameters: getAjaxParameters(element), + method: 'get', + onSuccess: function(transport) { + RedBox.showHtml('
' + transport.responseText + '
'); + }, + onFailure: function(transport) { + RedBox.close(); + } + }); + +} + +function getAjaxParameters(element) { + + if ($(element).id == 'reload_button' || $(element).id == 'edit_button') { + var widget = $(element).up(".widget").widget; + } else { + var widget = element; + } + + var id = widget._getId().substr(7); + + parameters = 'block=' + _widgets_blocks[id]; + parameters = parameters + '&widget=' + widget._getId(); + + p = _layout_params[id]; + for (a in p) { + if (typeof(p[a]) != 'string') { + break; + } + parameters = parameters + '&defaults[' + a + ']=' + p[a]; + } + + return parameters; +} + +function setParams() { + + widget_name = ''; + params = new Array(); + inputs = $('blockform').getElements(); + inputs.each(function(item) { + name = item.name.substr(0, 6); + if (name == 'params') { + pos = item.name.indexOf(']', 7); + param_name = item.name.substr(7, pos - 7); + if (item.type == 'checkbox') { + params[param_name] = item.checked; + } else { + params[param_name] = item.value; + } + } + if (name == 'widget') { + widget_name = item.value; + } + }); + + _layout_params[widget_name.substr(7)] = params; + + var widget = $(widget_name).widget; + reloadWidget(widget); + + cancelRedBox(); +} + +function noParams(widget_name, msg) { + + // alert(msg); + + var widget = $(widget_name).widget; + reloadWidget(widget); + + cancelRedBox(); +} + +function cancelRedBox() { + RedBox.close(); + return false; +} + +function savePortal() { + + parameters = portal.serialize(); + + for (var i = 0; i < _layout_params.length; i++) { + parameters = parameters + '¶ms[' + i + '][type]=' + _widgets_blocks[i]; + p = _layout_params[i]; + for (a in p) { + if (typeof(p[a]) != 'string') { + break; + } + parameters = parameters + '¶ms[' + i + '][' + a + ']=' + p[a]; + } + } + + new Ajax.Request(save_url, { + parameters: parameters, + method: 'post' + }); +} diff --git a/drag_n_drop_portal/lib/Block/Layout/View/js.php b/drag_n_drop_portal/lib/Block/Layout/View/js.php new file mode 100644 index 000000000..2e5cd23e9 --- /dev/null +++ b/drag_n_drop_portal/lib/Block/Layout/View/js.php @@ -0,0 +1,113 @@ + + * @since Horde 4 + * @package Horde_Block + */ +class Horde_Block_Layout_View_Js extends Horde_Block_Layout_View { + + /** + * Render the current layout as HTML. + * + * @return string HTML layout. + */ + function toHtml() + { + $html = '
'; + $js = ''; + + $js_init .= 'portal.addWidgetControls("control_buttons");' + . '}' + . 'document.observe("dom:loaded", init); +' + . ''; + + $html .= '
' . "\n" . $js . "\n" . $js_init; + + // Strip any CSS tags out of the returned content so + // they can be handled seperately. + if (preg_match_all('//', $html, $links)) { + $html = str_replace($links[0], '', $html); + $this->_linkTags = $links[0]; + } + + return $html; + } + + function _serializeBlock($js_id, $app, $name, $params, &$js_init, $col_num) + { + $block = Horde_Block_Collection::getBlock($app, $name, $params); + if ($block instanceof PEAR_Error) { + $title = $block->getMessage(); + $content = $block->getDebugInfo(); + $params = array(); + } else { + $content = @$block->getContent(); + if ($content instanceof PEAR_Error) { + $content = $content->getDebugInfo(); + } + $title = @$block->getTitle(); + if ($title instanceof PEAR_Error) { + $title = $title->getMessage(); + } else { + $title = strip_tags($title); + } + } + + $content = Horde_Serialize::serialize($content, SERIALIZE_JSON, NLS::getCharset()); + $title = Horde_Serialize::serialize($title, SERIALIZE_JSON, NLS::getCharset()); + $params = Horde_Serialize::serialize($params, SERIALIZE_JSON, NLS::getCharset()); + + $js_init .= 'portal.add(new Xilinus.Widget().' + . 'setTitle(title_' . $js_id .').' + . ' setContent(content_' . $js_id .'), ' . $col_num . ');' + . '_widgets_blocks[' . $js_id . '] = "' . $app . ':' . $name . '";' + . '_layout_params[' . $js_id . '] = \'' . $params . '\'.evalJSON();' + . 'delete title_' . $js_id .';' + . 'delete content_' . $js_id .';' . "\n"; + + return 'var content_' . $js_id . ' = ' . $content . ';' . "\n" + . 'var title_' . $js_id . ' = ' . $title . ';' . "\n"; + } +} diff --git a/drag_n_drop_portal/params.php b/drag_n_drop_portal/params.php new file mode 100644 index 000000000..92ff91466 --- /dev/null +++ b/drag_n_drop_portal/params.php @@ -0,0 +1,42 @@ + + * @package Folks + */ +define('HORDE_BASE', dirname(__FILE__) . '/..'); +require_once HORDE_BASE . '/lib/base.php'; +require_once 'Horde/Loader.php'; + +// Block to load +$block_id = Util::getFormData('block'); +list($app, $name) = explode(':', $block_id); + +// Load collection +$blocks = new Horde_Block_Collection(null, array($app)); + +// Create block params form +$params = $blocks->getParams($app, $name); +if (empty($params) || + !$blocks->isEditable($app, $name)) { + echo ''; +} else { + $block = &$blocks->getBlock($app, $name); + + $defaults = Util::getFormData('defaults'); + if (empty($defaults)) { + foreach ($params as $key => $val) { + $defaults[$key] = $val; + } + } + if (!isset($defaults['_refresh_time'])) { + $defaults['_refresh_time'] = 0; + } + require './templates/portal/params.php'; +} diff --git a/drag_n_drop_portal/save.php b/drag_n_drop_portal/save.php new file mode 100644 index 000000000..41057cd80 --- /dev/null +++ b/drag_n_drop_portal/save.php @@ -0,0 +1,39 @@ + + * @package Folks + */ +define('HORDE_BASE', dirname(__FILE__) . '/..'); +require_once HORDE_BASE . '/lib/base.php'; +require_once 'Horde/Loader.php'; + +if (!Auth::isAuthenticated()) { + Horde::authenticationFailureRedirect(); +} + +$layout = array(); +$params = Util::getPost('params'); +foreach ($_POST as $column => $rows) { + if (substr($column, 0, 11) != 'widget_col_') { + continue; + } + $col = (int)substr($column, 11); + foreach ($rows as $row => $widget) { + $id = (int)substr($widget, 7); + list($app, $name) = explode(':', $params[$id]['type']); + $layout[$row][$col] = array('app' => $app, + 'height' => 1, + 'width' => 1, + 'params' => array('type' => $name, + 'params' => $params[$id])); + } +} + +$prefs->setValue('portal_layout', serialize($layout)); diff --git a/drag_n_drop_portal/select.php b/drag_n_drop_portal/select.php new file mode 100644 index 000000000..855f69686 --- /dev/null +++ b/drag_n_drop_portal/select.php @@ -0,0 +1,36 @@ + + * @package Folks + */ +define('HORDE_BASE', dirname(__FILE__) . '/..'); +require_once HORDE_BASE . '/lib/base.php'; +require_once 'Horde/Loader.php'; + +?> +
+ +
+ +
+" onclick="return addWidget()" /> +" onclick="return cancelRedBox()" /> +
diff --git a/drag_n_drop_portal/templates/portal/params.php b/drag_n_drop_portal/templates/portal/params.php new file mode 100644 index 000000000..a917a10ff --- /dev/null +++ b/drag_n_drop_portal/templates/portal/params.php @@ -0,0 +1,37 @@ +

getName($app, $name)) ?>

+
+ + + + + +updateable): ?> + + + + + + + + + + + + + + +
  + +
getParamName($app, $name, $id) ?>: getOptionsWidget($app, $name, $id, $defaults) ?>
+" onclick="return setParams()" /> +" onclick="return cancelRedBox()" /> +
+
diff --git a/drag_n_drop_portal/themes/graphics/bottom_left.gif b/drag_n_drop_portal/themes/graphics/bottom_left.gif new file mode 100644 index 0000000000000000000000000000000000000000..d324686e3694c71603b4f37731a60829effae420 GIT binary patch literal 90 zcmZ?wbhEHb+|z`(+w1LA)2Td#JcUSBy^=p-Mr_W5Ea25SH-86FJ) literal 0 HcmV?d00001 diff --git a/drag_n_drop_portal/themes/graphics/bottom_right.gif b/drag_n_drop_portal/themes/graphics/bottom_right.gif new file mode 100644 index 0000000000000000000000000000000000000000..930a8cf0c08d6d0c087bffbb58a2a4be9884899c GIT binary patch literal 339 zcmV-Z0j&N}*y*TU5yZ>M)j$~<`XsWJk>%MR-&ona-I9~63@BhG{ za7Zi~kI1BQdAj8Y%&2rqty-_xtai)ocAPn{cuX#v&*-#z&9*(E?YMkSuiNkV{1L3v z`~QG}f`f#GQ+#lSii?bmj*pOjh>?_)mY0~Bnl6)@o}ZwhqN9O`iKM8hs;jK6K&Gdz zva__cwzseZ1G~JvzQ4f1!o$SH#>dFX%FE2n&d<=%($mz{*4NnC+S}aS-rwNi;^XAy zxo_y{>g(+7?(gvN^7Hid_V@Vt`uqI-{{H|23LHqVpuvL(6DnNDu%W|;5F<*QNU@^D lix@L%+{m#QqsNaRLy8Die6vn^*-Txf>&f%`;;s`q`y)-gbqEwLsLxf=fsbY$#l!2jA2S$bt9uQK83{{vI zI#jF~I%RMNlz}cV1VuRt2ZO&j?arVj; z(|`K(c3|7u2;gpRp65iD)Lag%(}84~;B#|GUb}|m_3PlXvtXGF;CWDUIViv-cXRXn zs0HEs*_2^uau5JfgrHIZR27Mt82~`oXrTY_A*5~>^27v^x~>V|&jQ%z?>{+^d|yb8 z10e*+G(V||h!CHgKzjKSWSWpXPcWjvD1ufjzK%W55w#kkb{mOXx1h|-AgI?7)ayuG zxPVl-jOff6Fxy7#d5%^rz8*zLFD^D6U4Ps=JS?O-9Ynjk5K)A1brm2&yt;~Et%gLa zg$1rFwli5Al z*qHsG8v$b9N3&eMx|hv9ud8Z&q-oR|AE(y%I2~yk)m1g#%VwW9%jK)F?~io6*XzOa zJT%|FWz~Fs>(BZ5@APNSzWpMOzgC3!8~`G~ekDo2b>`-N$xTl;3NK!;Y0IK?It^B- zRM`6Zy7I^Ve)2EJN%q4qk&NS1T8POs@EHL14sg4YbR5WXZ;bQMG|iw;CCbp3`02i_@%07*qoM6N<$f>ff70ssI2 literal 0 HcmV?d00001 diff --git a/drag_n_drop_portal/themes/graphics/edit.png b/drag_n_drop_portal/themes/graphics/edit.png new file mode 100644 index 0000000000000000000000000000000000000000..5ac2275018a9bcbbd6ef1ae484d6bf6144a7bd1c GIT binary patch literal 1204 zcmV;l1WWsgP)4Tx0C=30kxfe*Q51%sn@|)}32A23}N+D$3+9~1;PBIDw= zWTS{L9C*&lf%65q)KeTlW9r-;Q5K#YBpbRt1f;Z0KPAKN=3KV z-Kc_Yce)@P!0B5q15VHK6To?8lmXEM9DmOXKme0D##h=v?me*F?sTOc%{1WYBgm%{ubaT>}NarT5@&}c&Fh~fMG!;cnSOfDS zR+t2eQ}4P6)GKL8`?!sg#>b_xX!Z-A@`Lp(RlVSdy%k!Lbp2GtV z06-#<W{TU%Ro=etsoQ)5PI$5R=KYD3wZON~N;dw5qMG&D5Gxm+#) z!0Yvb&1U=C?RK=Zv~;^%t{I=hjt0Q5uCA`Xpr9Z_Cc7+T)?84j+H}hlwHOu_CNvt2 zBUY)V?f zFxhtSnVlLcJbRA+eN3l4Hb5ZYM5xsRI&pGJIxpxX42Dtrqh5=1-7lOUCr%ZIM@F7r zFb)qL+F2+RMvn}SOfM}h6Q|QjEEdbANEC4sKq4o%$tG!@B;{{@l8oA>_Pst90Ek4Q zc&%3ZK0YBK5g_n-y(ld$eKuqaqPS|{F(w19Ow%wk;@4?nH&$gX?cHr`hsoQUFIrDV;xo5jCKHqck`Tzg_WoKCg z01Xi?3GxdDa?t?8rrJ9kKxsWs7sn8ZsmTIP%seJS2@XsGjB<>QbqWujCAD#V_*k@I m^G2hM21P~**PYm>Gcg#2@~8j${jM6Qlfl!~&t;ucLK6T0fn84k literal 0 HcmV?d00001 diff --git a/drag_n_drop_portal/themes/graphics/plus.png b/drag_n_drop_portal/themes/graphics/plus.png new file mode 100644 index 0000000000000000000000000000000000000000..263e356901817a5ace857c6416481a8cc89faedc GIT binary patch literal 229 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!Wq?nJt4ZpT+GW?9SKZil=2`uU z>uqaqPS|{F(w19Ow%wk;@4?nH&$gX?cHr`hsoQUFIrDV;xo5jCKHqck`Tzg_WoKCg z01Xi?3GxdDa?t?8rrJ9kKxq$87sn8Z%gF*x%sdt>5)BNY4fE%VFixnOz;HxH;E|xf z6LzLNy|fh!^7`!7(%Qn@%IeHc+}hes+(!b!N}?k;cQW67Sy98yP|(Hueogq5a-f+E Mp00i_>zopr0454z8UO$Q literal 0 HcmV?d00001 diff --git a/drag_n_drop_portal/themes/graphics/redbox_spinner.gif b/drag_n_drop_portal/themes/graphics/redbox_spinner.gif new file mode 100644 index 0000000000000000000000000000000000000000..35218b31b5e09d98e59af8f8c17ab0c548b302b6 GIT binary patch literal 6820 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 literal 0 HcmV?d00001 diff --git a/drag_n_drop_portal/themes/graphics/reload.png b/drag_n_drop_portal/themes/graphics/reload.png new file mode 100644 index 0000000000000000000000000000000000000000..dcb020450dd0bfe53e5a9bd3c80e656ffb5d9e80 GIT binary patch literal 264 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 literal 0 HcmV?d00001 diff --git a/drag_n_drop_portal/themes/graphics/top_right.gif b/drag_n_drop_portal/themes/graphics/top_right.gif new file mode 100644 index 0000000000000000000000000000000000000000..e46ca3930566b5520c1ef2dda7c5d2d6e92e95e5 GIT binary patch literal 1123 zcmV-p1f2UvNk%w1Vdw)N0J8u900030|Ns8}{{8*^{QUg;`}_L(`uX|!`1ttu_xJYp z_VxAk^z`((xw-%U{{R30A^8LW000gEEC2ui0O$iB000F4(8)=wy*TU5yZ>M)j$~<` zXsWJk>%MR-&vb3yc&_h!@BhG{a7Zi~kI1BQ$!t2G(5Q4uty-_xtai)odcWYXcuX#v z&*-#z&2GEj@VIsu}^UuCK7Mva__cwzs&sy1Tr+zQ4f1!o$SH#>dFX%FE2n&d<=% z($mz{*4BX-*W29P-rwNi;^XAy=I7|?>g(Kq7wquy^7Hid_V@Vt`uqIM?iKw43LHqV zpuvL(6DnM&tAPcE5F<*QNU@^Dix}(un~<@i$B!WYLy8f9z%!p@&Sg9;r=v}I2RMUyIB%CxCdct@W~ol3Q;)vLLVGT6$stJkk! z!-^eCwyfE+Xw#})%eJlCw{YXiolCc_-Me`6>fOt?uiw9b0}CEZ7%;7)3lb|{%($`R z$B-jSo=my2<;$2eYu?Pcv**vCLyI0wy0q!js8g$6&APSg*RW&De!Vr;Q3bej>)y?~ zx9{J;g9{%{ytwh>$dfBy&b+zv=g^}|pH98H_3PNPYv0bjyZ7(l!+TH60M^k2=+moT z&%V9;_weJ(pHIKO{rmXy>)+46zyJRL1}NbFfCLt3;DHDxsNjMOHt67k5Ju=AZVQy> z%25bpsNsejcIe@UAciR7h$NP1;)y7xsN#w&w&>!EFvck3j5OA0ydtsG^* zq?A@_>7|%vs_CYjcIxS;poS{ysHB!^>Zz!vs_Lq&w(9Duu*NFuthCl@>#exvs_U-2 z=DMV#3Y2$L0mK$-?6JrutL(DOHtX#Fv(QE>?X=WZYwfkzW~=SC+;;2jx8Q~=?zrTZ zYwo$|rmOC{?6#}!q)Ivp=}`pKYwx}I=Bw|%{PyebzW@g;@W2EYZ1BMdC#>+o3^(lX z!w^R-@x&BYZ1KeyXRPtY9Cz&T#>5&BuL1!aHNeRzr>yeIEVu0P%P_|*^UO5YZ1c@H z=dAP2JooJL&p-z)^w2~XZS>JdC$03-OgHWH(@-~EZvi47kN^Wm383}XTzBpD*I*wdY`5+9+i=G%_uO>XZTH=H=dJhNeE045-+%`$_~3t|OaRpfAh1Bz pgg5T^s=D{xc<06RAkoQ41Z literal 0 HcmV?d00001 diff --git a/drag_n_drop_portal/themes/screen.css b/drag_n_drop_portal/themes/screen.css new file mode 100644 index 000000000..c4f3274fb --- /dev/null +++ b/drag_n_drop_portal/themes/screen.css @@ -0,0 +1,217 @@ + +/* Redbox styles. */ +#RB_overlay { + position: absolute; + z-index: 100; + width: 100%; + height: 100%; + top: 0; + left: 0; + right: 0; + bottom: 0; + min-height: 100%; + background-color: #000; + opacity: .6; + filter: alpha(opacity=60); +} +#RB_loading { + z-index: 101; + width: 66; + margin-left: auto; + margin-right: auto; + margin-top: 200px; + padding-bottom: 66px; + text-align: center; + background: url("graphics/redbox_spinner.gif") no-repeat bottom center; +} +#RB_window { + z-index: 102; + background-color: #fff; + display: block; + text-align: left; + overflow: hidden; + margin: 20px auto 0 auto; + position: absolute; +} + +#RB_confirm { + width: 20em; + padding: 1em; + border: 1px solid #ccc; + background: #ffc; +} +#RB_confirm input { + margin: .2em; +} + +#RB_info { + width: 30em; + padding: 1em; + border: 1px solid #ccc; + background: #ccf; +} +#RB_info input { + margin: .2em; +} + +/* Portal editing */ + +#page { + margin: 10px auto; +} + +#page1 { + float: left; + width: 45%; +} + +#page2 { + float: right; + width: 45%; +} + +#widget_col_0 { + float: left; + width: 30%; + background: #E6E6E6; +} + +#widget_col_1 { + width: 50%; + float: left; + background: #CCC; +} + +#widget_col_2 { + float: left; + width: 20%; + background: #B3B3B3; +} + +#widget_col_3 { + float: left; + width: 40%; + background: #B3B3B3; +} + +#widget_col_4 { + float: left; + width: 60%; + background: #E6E6E6; +} + +#control_buttons { + position: absolute; + right: 0px; + top: 10px; + width: 90px; +} + +#reload_button { + position: relative; + float: left; + width: 16px; + height: 16px; + background: url(graphics/reload.png); + behavior: url(png.htc); + margin-right: 5px; +} + +#minimize_button { + position: relative; + float: left; + width: 16px; + height: 16px; + background: url(graphics/minus.png); + behavior: url(png.htc); + margin-right: 5px; +} + +#maximize_button { + position: relative; + float: left; + width: 16px; + height: 16px; + background: url(graphics/plus.png); + behavior: url(png.htc); + margin-right: 5px; +} + +#edit_button { + position: relative; + float: left; + width: 16px; + height: 16px; + background: url(graphics/edit.png); + behavior: url(png.htc); + margin-right: 5px; +} + +#delete_button { + position: relative; + float: left; + width: 16px; + height: 16px; + background: url(graphics/delete.png); + behavior: url(png.htc); + margin-right: 5px; +} + +/* Sliding doors technique */ +.widget_nw { + background: transparent url(graphics/top_left.gif) no-repeat; + height: 30px; +} + +.widget_w { + border-left: 1px solid #B9B9B9; + margin-left: 5px; +} + +.widget_sw { + background: transparent url(graphics/bottom_left.gif) no-repeat; + height: 15px; +} + +.widget_title { + background: url(graphics/top_right.gif) repeat-x right top; + color: #123456; + font: bold 14px/25px Tahoma, Arial, sans-serif; + height: 26px; + margin: 0 0 0 15px; + padding: 5px 0 0 0 ; + text-align: center; + margin-left: 15px; +} + +.widget_content { + background-color: #FDFDFD; + color: #71777A; + font: normal 12px/1em Tahoma, Arial, sans-serif; + overflow: hidden; + padding: 5px; + border-right: 1px solid #B9B9B9; + margin-right: 5px; +} + +.widget_statusbar { + background: transparent url(graphics/bottom_right.gif) repeat-x right top; + font-size: 8px; + height: 15px; + margin-left: 11px; +} + +.widget_draggable { + cursor: move; +} + +/* Ghost */ +.widget_ghost { + background: #FFF; + opacity: 0.5; + filter: alpha(opacity=50); + position: relative; + border: 3px dashed #F00; + margin: 0px; + padding: 0; +} -- 2.11.0