ItEr14S13RFComportamentoGraficoPlanificador: Adjust scroll positions and sizes based on screen size recalculated with javascript

* Two separate vertical and horizontal scrollbars have been defined to be positioned permanently on the navigator
     right and bottom window borders.
   * Taskdetails and timetracker legend are now permanently shown while scrolling.
   * Pending fixes on watermark height recalculation.
   * Delete/add task behaviour to be reviewed unless changed for a tree.
This commit is contained in:
Lorenzo Tilve 2009-06-30 20:31:08 +02:00 committed by Javier Moran Rua
parent 6e3dbd2886
commit d97bc603d7
15 changed files with 257 additions and 75 deletions

View file

@ -7,6 +7,7 @@ import java.util.List;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.zkoss.ganttz.util.TaskBean; import org.zkoss.ganttz.util.TaskBean;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.HtmlMacroComponent; import org.zkoss.zk.ui.HtmlMacroComponent;
public class ListDetails extends HtmlMacroComponent { public class ListDetails extends HtmlMacroComponent {
@ -26,7 +27,7 @@ public class ListDetails extends HtmlMacroComponent {
} }
private List<TaskDetail> getTaskDetails() { private List<TaskDetail> getTaskDetails() {
List<Object> children = getChildren(); List<Object> children = getInsertionPoint().getChildren();
return Planner.findComponentsOfType(TaskDetail.class, children); return Planner.findComponentsOfType(TaskDetail.class, children);
} }
@ -42,7 +43,7 @@ public class ListDetails extends HtmlMacroComponent {
} }
private void removeDetail(TaskDetail taskDetail) { private void removeDetail(TaskDetail taskDetail) {
getChildren().remove(taskDetail); getInsertionPoint().getChildren().remove(taskDetail);
} }
public void addTask() { public void addTask() {
@ -73,9 +74,13 @@ public class ListDetails extends HtmlMacroComponent {
private TaskDetail addTask(TaskBean taskBean) { private TaskDetail addTask(TaskBean taskBean) {
TaskDetail taskDetail = TaskDetail.create(taskBean); TaskDetail taskDetail = TaskDetail.create(taskBean);
appendChild(taskDetail); getInsertionPoint().appendChild(taskDetail);
taskDetail.afterCompose(); taskDetail.afterCompose();
return taskDetail; return taskDetail;
} }
} private Component getInsertionPoint() {
return getFellow("insertionPoint");
}
}

View file

@ -11,4 +11,6 @@
</c:forEach> </c:forEach>
</div> </div>
</div>
</div> </div>

View file

@ -9,4 +9,11 @@
${z:redraw(child, null)} ${z:redraw(child, null)}
</c:forEach> </c:forEach>
</div> </div>
</div> </div>
<br/>
<div id="ganttpanel_scroller_x">
<div id="ganttpanel_inner_scroller_x"></div>
</div>
<div id="ganttpanel_scroller_y"><div id="ganttpanel_inner_scroller_y" /></div>

View file

@ -9,7 +9,7 @@
/*]]> */ /*]]> */
</script> </script>
<div id="${self.uuid}" z.type="ganttz.planner.Planner" ${self.outerAttrs}"> <div id="${self.uuid}" z.type="ganttz.planner.Planner" ${self.outerAttrs}>
<c:forEach var="child" items="${self.children}"> <c:forEach var="child" items="${self.children}">
${z:redraw(child, null)} ${z:redraw(child, null)}
</c:forEach> </c:forEach>

View file

@ -28,7 +28,7 @@ document.body.class = "yui-skin-sam";
var myLogReader = new YAHOO.widget.LogReader(myContainer);*/ var myLogReader = new YAHOO.widget.LogReader(myContainer);*/
</script> </script>
<div id="scroll_container">
<c:set var="self" value="${requestScope.arg.self}"/> <c:set var="self" value="${requestScope.arg.self}"/>

View file

@ -1,6 +1,9 @@
<?taglib uri="http://www.zkoss.org/dsp/web/core" prefix="c"?> <?taglib uri="http://www.zkoss.org/dsp/web/core" prefix="c"?>
<zk> <zk xmlns:n="http://www.zkoss.org/2005/zk/native">
<button label="${c:l('listdetails.add_task')}" <button label="${c:l('listdetails.add_task')}"
onClick="self.getParent().addTask();" /> onClick="insertionPoint.getParent().getParent().addTask();" />
<n:div id="listdetails_container">
</zk> <vbox class="listdetails" id="insertionPoint">
</vbox>
</n:div>
</zk>

View file

@ -19,4 +19,4 @@
top.endDateTextBox = endDateTextBox; top.endDateTextBox = endDateTextBox;
]]> ]]>
</zscript> </zscript>
</zk> </zk>

View file

@ -1,5 +1,6 @@
<?taglib uri="http://www.zkoss.org/dsp/web/core" prefix="c"?> <?taglib uri="http://www.zkoss.org/dsp/web/core" prefix="c"?>
<zk> <zk xmlns:n="http://www.zkoss.org/2005/zk/native">
<zscript><![CDATA[ <zscript><![CDATA[
top = self; top = self;
]]> ]]>
@ -14,6 +15,8 @@
</style> </style>
<n:div id="timetracker">
<vbox> <vbox>
<hbox> <hbox>
<button image="/zkau/web/ganttz/img/zoom_in.gif" forward="onIncrease"/> <button image="/zkau/web/ganttz/img/zoom_in.gif" forward="onIncrease"/>
@ -35,7 +38,7 @@
</columns> </columns>
<rows> <rows>
<row id="fake_row" style="height: 100px;"> <row id="fake_row" style="height: 100px;" class="fake_column timetracker_column${(each.even?'_myeven':'')}">
<div class="fake_column timetracker_column${(each.even?'_even':'')}" style="height: 100px;" forEach="${top.detailsSecondLevel}" /> <div class="fake_column timetracker_column${(each.even?'_even':'')}" style="height: 100px;" forEach="${top.detailsSecondLevel}" />
</row> </row>
</rows> </rows>
@ -49,4 +52,7 @@
</zscript> </zscript>
</vbox> </vbox>
</n:div>
</zk> </zk>

View file

@ -11,6 +11,8 @@ zkTask.HEIGHT = 10;
zkTask.HALF_HEIGHT = 5; zkTask.HALF_HEIGHT = 5;
zkTask.DEPENDENCY_PADDING = 4; zkTask.DEPENDENCY_PADDING = 4;
zkTask.HALF_DEPENDENCY_PADDING = 2; zkTask.HALF_DEPENDENCY_PADDING = 2;
// Task borders are default 1px
zkTask.getDD = function(cmp) { zkTask.getDD = function(cmp) {
if (typeof (cmp.created_dd) == 'undefined') { if (typeof (cmp.created_dd) == 'undefined') {
@ -70,7 +72,7 @@ zkTask.init = function(cmp) {
var resize2 = new YAHOO.util.Resize(cmp2, { var resize2 = new YAHOO.util.Resize(cmp2, {
handles : [ 'r' ], handles : [ 'r' ],
proxy : true, proxy : true,
maxWidth: cmp.clientWidth - 2 maxWidth: cmp.clientWidth - 2 // Considering 1px borders
}); });
resize2.on('resize', function(ev) { resize2.on('resize', function(ev) {
@ -89,7 +91,7 @@ zkTask.init = function(cmp) {
resize2 = new YAHOO.util.Resize(cmp2, { resize2 = new YAHOO.util.Resize(cmp2, {
handles : [ 'r' ], handles : [ 'r' ],
proxy : true, proxy : true,
maxWidth: cmp.clientWidth - 2 maxWidth: cmp.clientWidth - 2 // Considering 1px borders
}); });
if ( (cmp.clientWidth) < (cmp2.clientWidth) ) { if ( (cmp.clientWidth) < (cmp2.clientWidth) ) {
cmp2.style.width = cmp.clientWidth - 2 + 'px'; cmp2.style.width = cmp.clientWidth - 2 + 'px';
@ -181,7 +183,7 @@ zkTask.createArrow = function(cmp) {
mouseClickListener = function(e) { mouseClickListener = function(e) {
var parentNode = arrow.parentNode; var parentNode = arrow.parentNode;
var task; var task;
if (task = zkTask.isOverTask(cmp, arrow)) { if ((task = zkTask.isOverTask(cmp, arrow))) {
zkau.send( { zkau.send( {
uuid : cmp.id, uuid : cmp.id,
cmd : "addDependency", cmd : "addDependency",
@ -198,27 +200,23 @@ zkTask.createArrow = function(cmp) {
YAHOO.util.Event.on(document.body, 'click', mouseClickListener); YAHOO.util.Event.on(document.body, 'click', mouseClickListener);
}; };
/* This method is binded to the mouse click listener to
* determine if it is positioned over any task */
zkTask.isOverTask = function(cmp, arrow) { zkTask.isOverTask = function(cmp, arrow) {
var listtasksNode = document.getElementById("listtasks"); var listtasksNode = document.getElementById("listtasks");
var ganttPanelNode = document.getElementById("ganttpanel"); // var ganttPanelNode = document.getElementById("ganttpanel");
var ganttPanelNode = document.getElementById("scroll_container");
arrayTasks = zkTask.getElementsByAttribute(listtasksNode, "div", "z.type", arrayTasks = zkTask.getElementsByAttribute(
"ganttz.task.Task"); listtasksNode, "div", "z.type","ganttz.task.Task");
/* Cursor relative positions to #listtasks (439,160) and ganttPanel scroll */ var xpos = zkTask.xMouse - ganttPanelNode.offsetLeft + ganttPanelNode.scrollLeft;
var xpos = zkTask.xMouse - listtasksNode.offsetLeft var ypos = zkTask.yMouse - ganttPanelNode.offsetTop + ganttPanelNode.scrollTop
+ ganttPanelNode.scrollLeft; - listtasksNode.offsetTop;
var ypos = zkTask.yMouse - listtasksNode.offsetTop;
/*
* This way of getting cursor coordinates, is unable to calculate scrollbar
* offset.
*/
for ( var i = 0; i < arrayTasks.length; i++) { for ( var i = 0; i < arrayTasks.length; i++) {
var task = arrayTasks[i]; var task = arrayTasks[i];
if (((xpos) > (task.offsetLeft)) if (((xpos) > (task.offsetLeft))
&& ((xpos) < (task.offsetLeft + task.offsetWidth)) && ((xpos) < (task.offsetLeft + task.offsetWidth))
&& (ypos > (task.offsetTop)) && (ypos > (task.offsetTop))

View file

@ -1,6 +1,14 @@
HEIGHT_PER_ROW = 15; HEIGHT_PER_ROW = 15;
HEIGHT_TIME_TRACKER = 120; HEIGHT_TIME_TRACKER = 120;
MIN_RESOLUTION_X = 600;
MIN_RESOLUTION_Y = 600;
TASKDETAILS_WIDTH = 300
TIMETRACKER_OFFSET_TOP = 200
SCROLLBAR_WIDTH = 15
zkTasklist = {}; zkTasklist = {};
zkTasklist.init = function(cmp) { zkTasklist.init = function(cmp) {
@ -17,7 +25,7 @@ zkTasklist.adjust_height = function(cmp) {
offset = 0; offset = 0;
} }
var newheigth = parseInt(height) + offset; var newheigth = parseInt(height) + offset;
element.style["height"] = newheigth + 'px'; element.style["height"] = document.getElementById('scroll_container').style["height"];
} }
setHeight(document.getElementById('ganttpanel'), HEIGHT_TIME_TRACKER); setHeight(document.getElementById('ganttpanel'), HEIGHT_TIME_TRACKER);
@ -30,3 +38,73 @@ zkTasklist.adjust_height = function(cmp) {
setHeight(element,HEIGHT_PER_ROW); setHeight(element,HEIGHT_PER_ROW);
}); });
} }
//document.getElementById('scroll-container').onscroll = scrollEvent;
document.getElementById('ganttpanel_scroller_x').onscroll = scrollEvent;
function scrollEvent() {
//scroller = document.getElementById('scroll-container');
scroller = document.getElementById('ganttpanel_scroller_x');
document.getElementById('timetracker').scrollLeft = scroller.scrollLeft;
document.getElementById('scroll_container').scrollLeft = scroller.scrollLeft;
}
document.getElementById('ganttpanel_scroller_y').onscroll = scrollEvent_y;
function scrollEvent_y() {
//scroller = document.getElementById('scroll-container');
scroller = document.getElementById('ganttpanel_scroller_y');
document.getElementById('listdetails_container').scrollTop = scroller.scrollTop ;
document.getElementById('scroll_container').scrollTop = scroller.scrollTop ;
}
window.onresize = relocateScrolls;
window.onload = relocateScrolls;
// document.body.onresize = relocateScrolls;
function relocateScrolls() {
scroller_y = document.getElementById('ganttpanel_scroller_y');
scroller_x = document.getElementById('ganttpanel_scroller_x');
timetracker = document.getElementById('timetracker');
listdetails = document.getElementById('listdetails_container');
scroll_container = document.getElementById('scroll_container');
// Reposition scroll-y and scroll-x width (Width change)
if ( window.innerWidth > MIN_RESOLUTION_X ) {
scroller_y.style["left"] =
(window.innerWidth - SCROLLBAR_WIDTH*2) +"px";
scroller_x.style["width"] =
(window.innerWidth - TASKDETAILS_WIDTH - SCROLLBAR_WIDTH ) +"px";
timetracker.style["width"] = (window.innerWidth - TASKDETAILS_WIDTH
- SCROLLBAR_WIDTH - SCROLLBAR_WIDTH*2 ) +"px";
scroll_container.style["width"] = timetracker.style["width"];
}
// Reposition scroll-y and scroll-x width (Height change)
if ( window.innerHeight > MIN_RESOLUTION_Y ) {
scroller_x.style["top"] = (window.innerHeight - SCROLLBAR_WIDTH*2) +"px";
scroller_y.style["height"] = (window.innerHeight - TASKDETAILS_WIDTH ) +"px";
timetracker.style["height"] = (window.innerHeight - TIMETRACKER_OFFSET_TOP ) +"px";
listdetails.style["height"] = scroller_y.style["height"];
scroll_container.style["height"] = (window.innerHeight - TIMETRACKER_OFFSET_TOP - 90 ) +"px";
}
/* FIX: Needed to recalculate native watermark td */
adjustScrolls();
}
function adjustScrolls() {
// Resize scroller inner divs to adapt scrollbars lenght
document.getElementById('ganttpanel_inner_scroller_y').style["height"]
= document.getElementById('listdetails_container').scrollHeight + "px";
document.getElementById('ganttpanel_inner_scroller_x').style["width"]
= document.getElementById('timetracker').scrollWidth + "px";
}

View file

@ -22,7 +22,7 @@ public class DataForPlanner {
} }
public DependencyRegistry getLightLoad() { public DependencyRegistry getLightLoad() {
return getModelWith(40); return getModelWith(20);
} }
public DependencyRegistry getMediumLoad() { public DependencyRegistry getMediumLoad() {

View file

@ -4,7 +4,7 @@
<n:div class="logo"></n:div> <n:div class="logo"></n:div>
<n:div class="vision"></n:div> <n:div class="vision"></n:div>
</n:div> </n:div>
<menubar id="menubar" width="900px" top="0px" left="320px" <menubar id="menubar" width="800px" top="0px" left="320px"
ctrlKeys="^k#f2" onCtrlKey="doCtrlKey()" sclass="mainmenu"> ctrlKeys="^k#f2" onCtrlKey="doCtrlKey()" sclass="mainmenu">
<menu label="${c:l('mainmenu.plannification')}"> <menu label="${c:l('mainmenu.plannification')}">

View file

@ -1,4 +1,3 @@
<vbox id="orderElementTree">
<vbox> <vbox>
<hbox> <hbox>
<button label="New order element" <button label="New order element"

View file

@ -1,23 +1,26 @@
/* Planificator specific styles */ /* Planificator specific styles
/*** Tasks ***/ The next constants are used within the planner styling:
#listtasks {
position:relative;
width:600px;
top:70px;
}
LISTDETAILS_W = 280
HEIGHT_PER_ROW = 15;
HEIGHT_TIME_TRACKER = 120;
*/
/****** Tasks and dependencies ******/
.listdetails { .listdetails {
width:280px; width:280px; /* LISTDETAILS_W */
float:left; float:left;
margin-top:46px; margin-top: 0px;
border-bottom: 1px solid #86A4BE; border-bottom: 1px solid #86A4BE;
font-size:10px !important; font-size:10px !important;
} margin-top:0px;
.taskdetail_grid table {
height:30px;
width:280px;
} }
.listdetails img { .listdetails img {
@ -25,7 +28,7 @@
} }
.listdetails td { .listdetails td {
padding-left:0px; /* 3 */ padding-left:0px;
} }
.listdetails input { .listdetails input {
@ -36,10 +39,6 @@
height:17px; height:17px;
} }
.task_title {
width: 120px !important;
}
.listdetails .z-datebox-inp { .listdetails .z-datebox-inp {
font-family:"Verdana,Tahoma,Arial,Helvetica,sans-serif"; font-family:"Verdana,Tahoma,Arial,Helvetica,sans-serif";
font-size:10px !important; font-size:10px !important;
@ -47,6 +46,22 @@
border-right:0px; border-right:0px;
} }
.task_title {
width: 120px !important;
}
.taskdetail_grid table {
height:30px;
width:280px; /* LISTDETAILS_W */
}
#listtasks {
position:relative;
width:600px;
top:0px;
}
/* Task box properties */ /* Task box properties */
.yui-resize, .box { .yui-resize, .box {
border: 1px solid; border: 1px solid;
@ -67,7 +82,7 @@
} }
/*** Dependencies ***/ /****** Dependencies *******/
#listdependencies { #listdependencies {
position:relative; position:relative;
width:400px; width:400px;
@ -94,14 +109,37 @@
width:1px; width:1px;
} }
.completion {
display: none;
width: 30%;
margin-top:0px;
height: 10px;
background-color: #FFCC99;
z-index:5;
border:0px;
}
.row span {
display:none;
position:relative;
z-index:5;
color:#BBBBBB;
white-space:nowrap;
}
.zk #ganttpanel .z-button-cm {
border: 0px;
}
/* Width: ganttpanel constant, /* Width: ganttpanel constant,
Height: is recalculated on number of tasks */ Height: is recalculated on number of tasks */
#ganttpanel { #ganttpanel {
height:800px; height:400px; /* 800 */
width: 900px; width: 900px;
overflow-x: scroll;
} }
#ganttpanel table { #ganttpanel table {
float:left; float:left;
padding:0; padding:0;
@ -127,24 +165,70 @@ table {
border:0px; border:0px;
} }
.completion {
display: none;
width: 30%;
margin-top:0px;
height: 10px;
background-color: #FFCC99;
z-index:5;
border:0px;
}
.row span { #listdetails_container {
display:none; float:left;
overflow:hidden;
height:300px;
position:relative; position:relative;
z-index:5; top:50px;
color:#BBBBBB; overflow: hidden;
white-space:nowrap; border-bottom: 1px solid #86A4BE;
border-right: 1px solid #86A4BE;
} }
.zk #ganttpanel .z-button-cm {
border: 0px;
} #scroll_container {
margin-top:70px;
/* border:solid green 1px; */
height:300px; /* Recalculate based on window */
width:500px; /* Recalculate based on window */
overflow:hidden;
float:left;
position:absolute;
left:300px;
}
#timetracker {
position:absolute;
left:300px;
width:600px;
height:400px;
position:absolute;
overflow-x:hidden;
float:left;
/* border: solid 1px red; */
}
#ganttpanel_scroller_x, #ganttpanel_scroller_y {
position:absolute;
float:left;
overflow:auto;
}
#ganttpanel_scroller_x {
top: 600px; /* Calculate initial settings */
left: 280px;
width:635px;
height:15px;
}
#ganttpanel_inner_scroller_x {
/* must be resized on ganttpanel javascript adjust size */
width:1900px; /* Real canvas dimensions */
height:15px; /* Scroll constant */
}
#ganttpanel_scroller_y {
top: 270px; /* Calculate initial settings */
left: 920px;
width:15px;
height:330px;
}
#ganttpanel_inner_scroller_y {
width:15px; /* Scroll constant */
height:1350px; /* Modified when added or removed tasks, or zoom adjustments */
}

View file

@ -12,7 +12,7 @@
</zscript> </zscript>
<!-- choose lightLoad, mediumLoad or highLoad. <!-- choose lightLoad, mediumLoad or highLoad.
--> -->
<planner id="planner" self="@{define(content)}" dependencyRegistry="${plannerData.lightLoad}"> <planner id="planner" self="@{define(content)}" dependencyRegistry="${plannerData.mediumLoad}">
<div id="idContextMenuTaskAssigment" <div id="idContextMenuTaskAssigment"
use="org.zk.myhello.pages.MyHelloPageListener"> use="org.zk.myhello.pages.MyHelloPageListener">
</div> </div>