[rhmessaging-commits] rhmessaging commits: r3169 - mgmt/trunk/cumin/python/cumin.

rhmessaging-commits at lists.jboss.org rhmessaging-commits at lists.jboss.org
Wed Mar 18 14:32:18 EDT 2009


Author: eallen
Date: 2009-03-18 14:32:18 -0400 (Wed, 18 Mar 2009)
New Revision: 3169

Added:
   mgmt/trunk/cumin/python/cumin/visualizations.py
   mgmt/trunk/cumin/python/cumin/visualizations.strings
Log:
New slot vis files

Added: mgmt/trunk/cumin/python/cumin/visualizations.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/visualizations.py	                        (rev 0)
+++ mgmt/trunk/cumin/python/cumin/visualizations.py	2009-03-18 18:32:18 UTC (rev 3169)
@@ -0,0 +1,180 @@
+import logging
+
+from wooly.widgets import *
+from wooly import *
+from wooly.forms import *
+from wooly.resources import *
+from wooly.tables import *
+
+from widgets import *
+from stat import *
+from parameters import *
+from formats import *
+from util import *
+from job import *
+
+strings = StringCatalog(__file__)
+
+class SlotMap(Widget):
+    def __init__(self, app, name):
+        super(SlotMap, self).__init__(app, name)
+        
+        self.slot_info = self.SlotInfo(app, "slot_info")
+        self.add_child(self.slot_info)
+    
+        self.slot_legend = self.SlotLegend(app, "slot_legend")
+        self.add_child(self.slot_legend)
+        
+        self.wait = self.PleaseWait(app, "please_wait")
+        self.add_child(self.wait)
+    
+    def get_args(self, session):
+        return self.frame.get_args(session)
+
+    def render_href(self, session, object):
+        params = list()
+        cls = self.app.model.get_class_by_object(object).cumin_name
+        params.append("class=%s" % cls)
+        params.append("id=%s" % object.id)
+        params.append("zl=1")  # zoom level
+        params.append("zx=0") # zoom left
+        params.append("zy=0") # zoom top
+
+        return "slots.png?" + ";".join(params)
+    
+    def get_title_name(self, session, object):
+        return str(object.id)
+    
+    def render_title(self, session, object):
+        return "Slots on '%s'" % self.get_title_name(session, object)
+
+    def render_job_index_param(self, session, *args):
+        return "xargs"
+
+    def render_slot_job_url(self, session, *args):
+        job = Identifiable("XXX")
+        return self.page.main.pool.job.get_href(session, job)
+
+    def render_slot_clip_size(self, session, *args):
+        return 400
+
+    class PleaseWait(CuminForm):
+        def __init__(self, app, name):
+            super(SlotMap.PleaseWait, self).__init__(app, name)
+    
+            self.__cancel = self.Cancel(app, "cancel")
+            self.__cancel.set_tab_index(201)
+            self.add_child(self.__cancel)
+
+        def get_modal(self, session):
+            return False
+        
+        class Cancel(FormButton):
+            def render_class(self, session, *args):
+                return "cancel"
+    
+            def render_content(self, session, *args):
+                return "Cancel"
+    
+            def render_onclick(self, session, *args):
+                return "cancel_wait"
+            
+    class SlotLegend(Widget):
+        def __init__(self, app, name):
+            super(SlotMap.SlotLegend, self).__init__(app, name)
+            
+            self.states = self.SlotStates(app, "slot_states")
+            self.add_child(self.states)
+            
+            self.activities = self.SlotActivities(app, "slot_activities")
+            self.add_child(self.activities)
+            
+        class SlotStates(ItemSet):
+            states = ("Unclaimed", "Claimed", "Owner", "Matched", "Preempting")
+            
+            def do_get_items(self, session):
+                return self.states
+
+            def render_initial(self, session, state):
+                return state[0]
+            
+            def render_title(self, session, state):
+                return state
+                
+        class SlotActivities(ItemSet):
+            activities = [("Idle", "clear"), 
+                           ("Busy", "green"),
+                           ("Suspended", "red"),
+                           ("Vacating", "orange"),
+                           ("Killing", "blue"),
+                           ("Benchmarking", "yellow"),
+                           ("Unknown", "grey")]
+            
+            def do_get_items(self, session):
+                return self.activities
+
+            def render_title(self, session, activity):
+                return activity[0]
+            
+            def render_href(self, session, activity):
+                params = list()
+                params.append("dot=%s" % activity[0]) 
+        
+                return "slots.png?" + ";".join(params)
+
+            def render_dot_size(self, session, activity):
+                return 12
+            
+    class SlotInfo(ItemSet):
+        display_names = {"jid": "jid", "job_id": "Job ID", 
+                         "system": "System", "machine": "Machine", 
+                         "state": "State", "activity": "Activity", 
+                         "name": "Name"}
+
+        def __init__(self, app, name):
+            super(SlotMap.SlotInfo, self).__init__(app, name)
+            
+            self.info_index = IntegerParameter(app, "i")
+            self.add_parameter(self.info_index)
+            
+            self.info_div_tmpl = Template(self, "bg_html")
+            
+        def get_args(self, session):
+            return self.frame.get_args(session)
+        
+        def do_render(self, session, *args):
+            object = args[0]
+            info_index = self.info_index.get(session)
+            if info_index is not None:
+                #print "rendering slot info for %i" % info_index
+                cls = self.app.model.get_class_by_object(object)
+                action = cls.get_visualization_action()
+                slot_info = action.get_boxes(session, object)
+                writer = Writer()
+                self.info_div_tmpl.render(writer, session, slot_info[info_index])
+                return writer.to_string()
+            else:
+                return super(SlotMap.SlotInfo, self).do_render(session, *args)
+            
+        def do_get_items(self, session, slot):
+            return ((self.display_names[x], slot[x]) 
+                    for x in slot if x in self.display_names)
+        
+        def render_slot_info_url(self, session, *args):
+            return self.page.get_update_url(session, [self])
+            
+        def render_slot_info_index(self, session, *args):
+            return self.info_index.path
+        
+        def render_title(self, session, item):
+            return item[0]
+    
+        def render_value(self, session, item):
+            return item[1]
+        
+        def render_job_id(self, session, item):
+            return item[0] == "jid" and "id='job_id'" or ""
+        
+        def render_row_class(self, session, item):
+            return item[0] == "jid" and "class='hidden_row'" or ""
+            

Added: mgmt/trunk/cumin/python/cumin/visualizations.strings
===================================================================
--- mgmt/trunk/cumin/python/cumin/visualizations.strings	                        (rev 0)
+++ mgmt/trunk/cumin/python/cumin/visualizations.strings	2009-03-18 18:32:18 UTC (rev 3169)
@@ -0,0 +1,1225 @@
+[SlotMap.javascript]
+var vis;
+(function() {
+    vis = new Visualization();
+    var slot_clip_left;
+    var slot_clip_top;
+    var slot_zoom;
+    var slot_last_index;
+    var slot_info_timer;
+    var slot_hover_timer;
+    var slot_png_timer;
+    var slot_zoom_initialized;
+    var slot_center_index;
+
+    function Visualization() {
+        slot_clip_left = 0;
+        slot_clip_top = 0;
+        slot_zoom = 1;
+        slot_last_index = -1;
+        slot_info_timer = null;
+        slot_hover_timer = null;
+        slot_png_timer = null;
+        slot_zoom_initialized = false;
+        slot_center_index = -1;
+
+        this.pan_left = function () {
+            if (slot_clip_left == 0) return;
+            var now = new Date();
+            animate_pan(slot_clip_left, Math.min(Math.floor(slot_clip_size / 1.1), -slot_clip_left), (now-0), "slot_clip_left");
+        }
+        this.pan_right = function () {
+            var to_pan = Math.floor(slot_clip_size / 1.1);
+            if (slot_clip_left - slot_clip_size - to_pan < -slot_map_info.width) {
+                to_pan = slot_map_info.width - slot_clip_size + slot_clip_left;
+            }
+            var now = new Date();
+            animate_pan(slot_clip_left, -to_pan, (now-0), "slot_clip_left");
+        }
+        this.pan_up = function () {
+            if (slot_clip_top == 0) return;
+            var now = new Date();
+            animate_pan(slot_clip_top, Math.min(Math.floor(slot_clip_size / 1.1), -slot_clip_top), (now-0), "slot_clip_top");
+        }
+        this.pan_down = function () {
+            if (slot_map_info.height < slot_clip_size) return;
+
+            var to_pan = Math.floor(slot_clip_size / 1.1);
+            if (slot_clip_top - slot_clip_size - to_pan < -slot_map_info.height) {
+                to_pan = slot_map_info.height - slot_clip_size + slot_clip_top;
+            }
+            var now = new Date();
+            animate_pan(slot_clip_top, -to_pan, (now-0), "slot_clip_top");
+        }
+
+
+        // in case server stops and then restarts, reget the images
+        this.img_error = function (oImg) {
+            stop_auto_updates();
+            var oZooming = document.getElementById("slot_zooming");
+            if (oZooming) {
+                oZooming.style.display = "none";
+            }
+            oImg.style.visibility = "hidden"; // hide broken image indicator
+            slot_map_info.size = 0;
+            slot_map_info.width = 1;
+            slot_map_info.height = 1;
+            slot_map_info.rows = 1;
+            slot_map_info.cols = 1;
+            slot_map_info.count = 0;
+            slot_png_timer = setInterval(update_png, 10000);
+        }
+        this.img_loaded = function (oImg) {
+            stop_auto_updates();
+            var oZooming = document.getElementById("slot_zooming");
+            if (oZooming) {
+                oZooming.style.display = "none";
+            }
+
+            if (oImg) {
+                oImg.style.visibility = "visible";
+                slot_cookie_info();
+                oImg.width = slot_map_info.width;
+                oImg.height = slot_map_info.height;
+                set_pan("slot_panup", "width", slot_map_info.size * slot_map_info.cols, this.pan_up);
+                set_pan("slot_pandown", "width", slot_map_info.size * slot_map_info.cols, this.pan_down);
+                set_pan("slot_panleft", "height", slot_map_info.size * slot_map_info.rows, this.pan_left);
+                set_pan("slot_panright", "height", slot_map_info.size * slot_map_info.rows, this.pan_right);
+                
+                var oMap = document.getElementById(slot_current_id);
+                if (oMap) {
+                    oMap.style.width = Math.min(oImg.width, slot_clip_size) + "px";
+                    oMap.style.height = Math.min(oImg.height, slot_clip_size) + "px";
+                    if ((slot_map_info.size * slot_map_info.rows < slot_clip_size) &&
+                        (slot_map_info.size * slot_map_info.cols < slot_clip_size))
+                            oMap.style.borderColor = "transparent";
+                    else
+                            oMap.style.borderColor = "#CCCCCC";
+                    
+                }
+                var oGlass = document.getElementById("slot_glass");
+                if (oGlass) {
+                    oGlass.style.width = Math.min(oImg.width, slot_clip_size) + "px";
+                    oGlass.style.height = Math.min(oImg.height, slot_clip_size) + "px";
+                }
+                if (!slot_zoom_initialized)
+                    initialize_zoom();
+
+                animate_zoom_to(slot_zoom);
+                var oControls = document.getElementById("slot_controls");
+                if (oControls) {
+                    var oMap = document.getElementById(slot_current_id);
+                    oControls.style.left = (oMap.offsetLeft + oMap.offsetWidth - oControls.offsetWidth) + "px";
+                    //oControls.style.left = (420 - oControls.offsetWidth) + "px";
+                }
+                refire_info();
+            }
+            center_on_index();
+            draw_clipped();
+            slot_png_timer = setInterval(update_png, 6000);
+        }
+
+        this.upGlass = function (e) {
+            if (!e) var e = window.event;
+            var oGlass = document.getElementById("slot_glass");
+            if (oGlass) {
+                if (oGlass.dragging) {
+                    oGlass.dragging = false;
+                }
+            }
+        }
+            
+        this.moveGlass = function (e) {
+            if (slot_map_info.size == 0) return;
+            if (!e) var e = window.event;
+            var oGlass = document.getElementById("slot_glass");
+            if (oGlass) {
+                if (oGlass.dragging) {
+                    var posxy = get_event_pos(e);
+                    if ((posxy.x - oGlass.down_pos.x > 0) || (posxy.y - oGlass.down_pos.y > 0))
+                        oGlass.down_pos = {x: posxy.x - slot_clip_left, y: posxy.y - slot_clip_top};
+                    
+                    slot_clip_left = Math.min(posxy.x - oGlass.down_pos.x, 0);
+                    slot_clip_top = Math.min(posxy.y - oGlass.down_pos.y, 0);
+                    oGlass.drug = true;
+                    
+                    draw_clipped();
+                    if (e.preventDefault)
+                        e.preventDefault();
+                    return false;
+                }
+            }
+
+            var rpos = get_relative_event_pos(e);
+            if (rpos) {
+                get_slot_info(rpos.x, rpos.y);
+            }
+        }
+
+        this.downGlass = function (e) {
+            if (!e) var e = window.event;
+
+            var oGlass = document.getElementById("slot_glass");
+            if (oGlass) {
+                oGlass.dragging = true;
+                var posxy = get_event_pos(e);
+                oGlass.down_pos = {x: posxy.x - slot_clip_left, y: posxy.y - slot_clip_top};
+                clear_hover();
+                hide_info();
+            }
+            return false;        
+        }
+
+        this.outGlass = function outGlass(e) {
+            if (!e) var e = window.event;
+            clear_hover();
+            hide_info();
+        }
+
+        this.zoom_in_slots = function (posxy) {
+            if (slot_zoom >= get_max_zoom()) return;
+            var click_info = get_index(posxy.x, posxy.y);
+            slot_center_index = click_info.index;    
+            do_zoom(slot_zoom + 1);
+        }
+
+        this.fire_slot_info = function (index) {
+            slot_last_index = index;
+            slot_info_timer = null;
+            do_info_request(index);
+        }
+
+    }
+
+    function slot_zoom_to(e) {
+        if (!e) var e = window.event;
+        var targ = get_event_target(e);
+        var level = parseInt(targ.level, 10);
+
+        get_center_index();
+        do_zoom(level);
+        
+        if (e.stopPropagation)
+            e.stopPropagation()
+        else if (e.cancelBubble)
+            e.cancelBubble = true;
+    }
+
+    function do_zoom(level) {
+        var old_zoom = slot_zoom;
+        slot_zoom = level;
+        
+        stop_auto_updates();
+        var oZooming = document.getElementById("slot_zooming");
+        if (oZooming) {
+            oZooming.style.display = "block";
+            var oMap = document.getElementById(slot_current_id);
+            if (oMap) {
+                oZooming.style.width = oMap.offsetWidth + "px";
+            }
+        }
+        var oImg = document.images[slot_current_id];
+        if (oImg) {
+            var src = oImg.src;
+            src = replace_value(src, "zl", level, ";");
+            src = replace_value(src, "zx", slot_clip_left, ";");
+            src = replace_value(src, "zy", slot_clip_top, ";");
+
+            src = refreshTime(src);
+            oImg.src = src;
+        }
+
+        animate_zoom_to(level);
+        return false;
+    }
+
+    function animate_zoom_to(level) {
+        var oPos = document.getElementById("zoom_pos");
+        if (oPos) {
+            var original_x = oPos.offsetLeft;
+            var now = new Date();
+            var x_amount = ((level - 1) * 13) - original_x;
+            animate_zoom_pos(original_x, (now-0), x_amount)        
+        }
+    }
+    function animate_zoom_pos(original_x, original_time, x_amount) {
+        var oPos = document.getElementById("zoom_pos");
+        if (oPos) {
+            var now = new Date();
+            var delta = (now - original_time) / 400.0;
+            var partial = 1;
+            if (delta < 1)
+                partial = Math.sin(Math.PI/2 * delta);
+            oPos.style.left = Math.floor(original_x + x_amount * partial) + "px";
+                
+            if (delta < 1)
+                setTimeout(function(){ animate_zoom_pos(original_x, original_time, x_amount) }, 10);
+        }
+     }
+
+    function stop_auto_updates() {
+        if (slot_png_timer) {
+            clearInterval(slot_png_timer);
+            slot_png_timer = null;
+        }    
+    }
+
+    function update_png() {
+        stop_auto_updates();
+        updateChart(slot_current_id, null);
+    }
+
+    function set_pan(id, which, value, fn) {
+        var obj = document.getElementById(id);
+        if (obj) {
+            if (value < slot_clip_size) {
+                eval("obj.style." + which + " = '" + Math.min(value, slot_clip_size) + "px'");
+                obj.style.visibility = "hidden";
+                obj.onclick = null;
+            } else {
+                eval("obj.style." + which + " = '" + Math.min(value, slot_clip_size) + "px'");
+                obj.style.visibility = "visible";
+                obj.onclick = fn;
+            }
+        }
+    }
+
+
+    function slot_cookie_info() {
+        var slot_info = get_cookie("slot_info");
+        if (slot_info) {
+            var vals = slot_info.split("|");
+            if (vals.length == 6) {
+                slot_map_info.size = parseInt(vals[0], 10);
+                slot_map_info.width = parseInt(vals[1], 10);
+                slot_map_info.height = parseInt(vals[2], 10);
+                slot_map_info.count = parseInt(vals[3], 10);
+                slot_map_info.rows = parseInt(vals[4], 10);
+                slot_map_info.cols = parseInt(vals[5], 10);
+            }
+        }
+    }
+
+    function center_on_index() {
+        if (slot_center_index == -1) return;
+        
+        var row = slot_center_index % slot_map_info.cols;
+        var col = Math.floor(slot_center_index / slot_map_info.cols);
+        var x = col * slot_map_info.size + slot_map_info.size / 2;
+        var y = row * slot_map_info.size + slot_map_info.size / 2;
+        
+        var cl = (Math.min(slot_clip_size, slot_map_info.width) / 2) - x;
+        var ct = (Math.min(slot_clip_size, slot_map_info.height) / 2) - y;
+
+        if (slot_map_info.width + cl < slot_clip_size)
+            cl = slot_clip_size - slot_map_info.width;
+            
+        if (slot_map_info.height + ct < slot_clip_size)
+            ct = slot_clip_size - slot_map_info.height;  
+
+        if (cl > 0) cl = 0;
+        if (ct > 0) ct = 0;
+
+        slot_clip_left = Math.floor(cl);
+        slot_clip_top = Math.floor(ct);
+        slot_center_index = -1;
+    }
+
+    function get_center_index() {
+        var rx = Math.min(slot_clip_size, slot_map_info.width) / 2;
+        var ry = Math.min(slot_clip_size, slot_map_info.height) / 2;
+        
+        var click_info = get_index(rx, ry);
+        if (click_info)
+            slot_center_index = click_info.index;    
+    }
+
+    function get_max_zoom() {
+        // allow to zoom until each slot is at least 28px wide
+        return Math.ceil(28 / (slot_map_info.size / slot_zoom));
+    }
+    function initialize_zoom() {
+        var max_zoom = get_max_zoom();
+        var oZoom = document.getElementById("zoom_levels");
+        if ((oZoom) && (max_zoom > 1)) {
+            var oDiv, oText, oNode;
+            for (var i=0; i<max_zoom; i++) {
+                var oDiv = document.createElement("div");
+                if (i == 0) {
+                    oDiv.className = "zoom_first";
+                    oDiv.onclick = slot_zoom_to;
+                    oDiv.level = i+1;
+                    set_text(oDiv, (i+1)+ "", "zoom_node");
+                } else if (i == max_zoom - 1) {
+                    oDiv.className = "zoom_last";
+                    oDiv.onclick = slot_zoom_to;
+                    oDiv.level = i+1;
+                    set_text(oDiv, i+1, "zoom_node_last");
+                } else {
+                    oDiv.className = "zoom_middle_left";
+                    oDiv.onclick = slot_zoom_to;
+                    oDiv.level = i+1;
+                    oZoom.appendChild(oDiv);        
+                    oDiv = document.createElement("div");
+                    oDiv.className = "zoom_middle_right";
+                    oDiv.onclick = slot_zoom_to;
+                    oDiv.level = i+1;
+                    set_text(oDiv, (i+1)+ "", "zoom_node");
+                }
+                oZoom.appendChild(oDiv);
+            }
+        } else {
+            var oControls = document.getElementById("slot_controls");
+            if (oControls) {
+                oControls.style.display = "none";
+            }
+        }
+        var oVis = document.getElementById("slot_visualization");
+        if (oVis) {
+            oVis.style.visibility = "visible";
+        }
+        slot_zoom_initialized = true;
+
+        function set_text(odiv, text, className) {
+            var oText = document.createElement("div");
+            var oNode = document.createTextNode(text+"");
+            oText.className = className;
+            oText.appendChild(oNode);
+            odiv.appendChild(oText);
+            oText.onclick = slot_zoom_to;
+            oText.level = text;
+        }
+    }
+
+    function draw_clipped() {
+
+        var clip_bottom;
+        var clip_right;
+        if (slot_map_info.width < slot_clip_size) {
+            clip_bottom = slot_map_info.height;
+            clip_right = slot_map_info.width;
+            slot_clip_left = 0;
+            slot_clip_top = 0;            
+        } else {
+            var iZoom = slot_zoom;
+            var clip_width = slot_clip_size;
+            var clip_height = slot_clip_size;
+            clip_bottom = clip_height - slot_clip_top;
+            clip_right = clip_width - slot_clip_left;
+        
+            if (clip_right > slot_map_info.width) {
+                slot_clip_left += (clip_right - slot_map_info.width);
+                clip_right = slot_map_info.width;
+            }
+            if (clip_bottom > slot_map_info.height) {
+                slot_clip_top = Math.min(clip_height - slot_map_info.height, 0);
+                clip_bottom = slot_map_info.height;
+            }
+        }
+        
+        var oPng = document.getElementById("slot_png");
+        if (oPng) {
+            oPng.style.left = slot_clip_left + "px";
+            oPng.style.top = slot_clip_top + "px";
+            oPng.style.clip = "rect(" + (-slot_clip_top) + "px " + clip_right + "px " + clip_bottom + "px " + (-slot_clip_left) + "px)";
+        }
+    }
+
+
+    function animate_pan(original_edge, move, timer, which) {
+        var now = new Date();
+        var delta = (now - timer) / 400.0;
+        var expression = "=Math.floor(original_edge + move";
+        if (delta < 1) {
+            expression += " * Math.sin(Math.PI/2 * delta)";
+        }
+        expression += ")";
+        eval(which + expression);
+        draw_clipped();
+        if (delta < 1)
+            setTimeout( function () {animate_pan(original_edge, move, timer, which) }, 10);
+        
+    }
+
+    function clear_hover() {
+        if (slot_info_timer) {
+            clearTimeout(slot_info_timer);
+            slot_info_timer = null;
+            slot_last_index = -1;
+        }
+        oHover = document.getElementById("slot_hover");
+        if (oHover) {
+            oHover.style.visibility = "hidden";
+        }
+    }
+    function hide_info() {
+        oInfo = get_slot_info_elem();
+        if (oInfo) {
+            oInfo.style.visibility = "hidden";
+        }
+        slot_last_index = -1;
+    }
+             
+    function get_index(x, y) {
+        var width = slot_map_info.size;
+        var pngrow = Math.floor((y - slot_clip_top) / width);
+        var pngcol = Math.floor((x - slot_clip_left) / width);
+        if ((pngcol < slot_map_info.cols) && (pngrow < slot_map_info.rows)) {
+            var index = pngrow * slot_map_info.cols + pngcol;
+            if (index < slot_map_info.count)
+                return {"index": index, "row": pngrow, "col": pngcol};
+        }
+        return null;
+    }
+
+    function get_slot_info(rx, ry) {
+
+        var click_info = get_index(rx, ry);
+        if (click_info) {
+            if (click_info.index != slot_last_index) {
+                if (slot_info_timer) {
+                    clearTimeout(slot_info_timer);
+                    slot_info_timer = null;
+                }
+                if (slot_hover_timer) {
+                    clearTimeout(slot_hover_timer);
+                    slot_hover_timer = null;
+                }
+                slot_info_timer = setTimeout( function() { vis.fire_slot_info(click_info.index) }, 500); 
+                animate_hover(0, click_info.row, click_info.col);
+                oInfo = get_slot_info_elem();
+                if (oInfo) {
+                    oInfo.style.display = "none";
+                }
+            }
+        }
+    }
+    function animate_hover(leg, row, col) {
+        var oHover = document.getElementById("slot_hover");
+        if (oHover) {
+            if (slot_hover_timer) {
+                clearTimeout(slot_hover_timer);
+                slot_hover_timer = null;
+            }
+            var width = slot_map_info.size;
+            if (width == 0) return;
+            var rx = col * width + slot_clip_left;
+            var ry = row * width + slot_clip_top;
+            oHover.style.width = (width-1) + "px";
+            oHover.style.height = (width-1) + "px";
+            
+            switch (leg) {
+            case 0: 
+                    oHover.style.left = rx + "px";
+                    oHover.style.top = ry + "px";
+                    oHover.style.width = width + "px";
+                    oHover.style.height = width + "px";
+                    oHover.style.borderColor = "red pink pink pink";
+                    oHover.style.visibility = "visible";
+                    if ((rx < 0) || (ry < 0) || (rx + width > slot_clip_size) || (ry + width > slot_clip_size)) {
+                        var cx = (rx < 0) ? rx : 0;
+                        var cy = (ry < 0) ? ry : 0;
+                        var cw = (rx + width > slot_clip_size) ? slot_clip_size - rx  : width + 1;
+                        var ch = (ry + width > slot_clip_size) ? slot_clip_size - ry  : width + 1;
+                        oHover.style.clip = "rect(" + (-cy) + "px " + (cw) + "px " + (ch) + "px " + (-cx) + "px)";
+                    } else {
+                        oHover.style.clip = "rect(0px " + (width+1) + "px " + (width+1) + "px 0px)";
+                    }                
+                    slot_hover_timer = setTimeout( function() {animate_hover(1)}, 500/3);
+                    break;
+            case 1: oHover.style.borderColor = "red red pink pink";
+                    slot_hover_timer = setTimeout( function() {animate_hover(2)}, 500/3);
+                    break;
+            case 2: oHover.style.borderColor = "red red red pink";
+                    slot_hover_timer = setTimeout( function() {animate_hover(3)}, 500/3);
+                    break;
+            case 3: oHover.style.borderColor = "red red red red";
+                    break;
+            }
+        }
+    }
+    function get_slot_info_elem() {
+        return document.getElementById(slot_info_id);
+    }
+        
+    function refire_info() {
+        if (slot_last_index > -1) {
+            do_info_request(slot_last_index)
+        }
+    }
+
+    function do_info_request(index) {
+        args = slot_info_url.split("?");
+        var session = get_value(args[1], "session", ";")
+        sess = unescape(session);
+        sess = sess + ";" + slot_info_index + "=" + index;
+        sess = escape(sess);
+        var newreq = replace_value(slot_info_url, "session", sess, ";");
+          
+        wooly.directUpdate(newreq, got_slot_info, 0, {index: index});
+    }
+
+    function got_slot_info(xhtml, args) {
+        if (slot_last_index == -1) return;
+        var oInfo = get_slot_info_elem();
+        var for_jid = null;
+        if (oInfo) {
+            oInfo.style.display = "none";
+            if (oInfo.for_jid) {
+                for_jid = oInfo.for_jid;
+                oInfo.for_jid = null;
+            }
+        }
+        wooly.updatePage(xhtml);
+        var oInfo = get_slot_info_elem();
+        if (oInfo) {
+            oInfo.click_index = args.index;
+            oInfo.for_jid = null;
+            if (for_jid) {
+                clicks.doClick(for_jid.x, for_jid.y);
+                return;
+            }            
+
+            promote_to_body(oInfo); // so position is absolute to entire page
+
+            oInfo.style.left = "-1000px";
+            oInfo.style.visibility = "hidden";
+            oInfo.style.display = "block";
+            
+            var oMap = document.getElementById(slot_current_id);
+            if (oMap) {
+                var abs_pos = findPos(oMap);
+
+                // top of clicked slot is here
+                var y = Math.floor(args.index / slot_map_info.cols) * slot_map_info.size + slot_clip_top;
+
+                // candidate pos for popup
+                var top = (abs_pos.y + y) + Math.floor(slot_map_info.size * 1.5);
+
+                // if off the bottom of the map
+                if (top + oInfo.offsetHeight > abs_pos.y + oMap.offsetHeight) {
+                    // position popup above clicked slot
+                    top = (abs_pos.y + y) - oInfo.offsetHeight - Math.floor(slot_map_info.size * .5); 
+                }
+                oInfo.style.top = top + "px";
+                oInfo.style.left = abs_pos.x + "px";
+            }
+            oInfo.style.visibility = "visible";
+        }
+    }
+            
+
+}())
+
+
+var clicks;
+(function() {
+    clicks = new Clicks();
+
+    function Clicks() {
+         this.doubleclick_when = 0;
+         this.click_when = 0;
+         this.click_handle = null;
+
+        this.doMouseDown = function(e) {
+            if (!e) var e = window.event;
+            var which = e.type;    
+            switch (which) {
+             case "click": 
+               // If we've just had a doubleclick then ignore it
+               if (hadDoubleClick()) return false;
+               // Otherwise set timer to act.  It may be preempted by a doubleclick.
+               d = new Date();
+               this.click_when = d.getTime();
+                var rpos = get_relative_event_pos(e);
+                if (rpos) {
+                    this.click_handle = setTimeout( function() {clicks.doClick(rpos.x, rpos.y)}, 250);
+                    break;
+                }
+             case "dblclick":
+               doDoubleClick(e);
+               break;
+             default:
+           }
+        }
+
+        this.doClick = function(x, y) {
+            // preempt if DC occurred after original click.
+            if (this.click_when - this.doubleclick_when <= 0) {
+                return false;
+            }
+            var oGlass = document.getElementById("slot_glass");
+            if (oGlass) {
+                if (oGlass.drug) {
+                    oGlass.drug = false;
+                    return false;
+                }
+            }
+            var click_info = get_index(x, y);
+            var oInfo = get_slot_info_elem();
+            if (oInfo && click_info) {
+                if ((typeof oInfo.click_index != "undefined") && 
+                    (oInfo.click_index == click_info.index)) {
+                    // we already fetched the info for this slot
+                    var oInfoCell = document.getElementById("job_id");
+                    if (oInfoCell) {
+                        var jid = oInfoCell.innerHTML;
+                        if (jid != "") {
+                            go_to_job(jid);
+                            return false;
+                        }
+                    }
+                } else {
+                    // fetch the slot info so we can get the job id
+                    oInfo.for_jid = {fetching: true, x: x, y: y};
+                    vis.fire_slot_info(click_info.index);
+                }            
+            }
+            function go_to_job(jid) {
+                var url = show_slot_job_url.replace("XXX", jid+""); 
+                window.location.href = url;
+                show_wait();
+            }
+        }
+    }
+
+    function hadDoubleClick() {
+       var d = new Date();
+       var now = d.getTime();
+       if ((now - this.doubleclick_when) < 100) {
+         return true;
+       }
+       return false;
+    }
+     
+     function doDoubleClick(e) {
+       var now = new Date();
+       this.doubleclick_when = now.getTime();
+       if (this.click_handle != null) {
+         clearTimeout(this.click_handle);          // Clear pending Click  
+         this.click_handle = null;
+       }
+       if (!e) var e = window.event;
+       var posxy = get_relative_event_pos(e);
+       vis.zoom_in_slots(posxy);
+     }
+}())
+
+/* generic get value from cookie */
+function get_cookie(name) {
+    return get_value(document.cookie, name, ";");
+}
+
+/* generic get value from string */
+function get_value(s, name, sep) {
+    var name_plus = name + "=";
+    var crumbs = s.split(sep);
+    // splitting to avoid false match on substring:
+    // ex: bigfoo=duh;foo=blah;
+    for(var i=0; i < crumbs.length; i++) {
+        var c = crumbs[i];
+        while (c.charAt(0) == ' ') {
+            c = c.substring(1, c.length);
+        }
+            
+        if (c.indexOf(name_plus) == 0) {
+            return c.substring(name_plus.length,c.length);
+        }
+    }
+    return null;
+}
+
+/* generic replace a value in a name=value; string */
+function replace_value(s, name, value, sep) {
+    var name_index = s.indexOf(name+"=");
+    if (name_index > -1) {
+        var sep_index = s.indexOf(sep, name_index);
+        if (sep_index == -1) { // end of string
+            sep_index = s.length;
+        }
+        var s1 = s.substring(0, name_index + name.length + 1);
+        var s2 = value + "";
+        var s3 = s.substring(sep_index);
+        return s1 + s2 + s3;
+    }
+    return s;
+}
+
+/* get the absolute position of something */
+function findPos(obj) {
+    var curleft = curtop = 0;
+    if (obj.offsetParent) {
+        do {
+                curleft += obj.offsetLeft;
+                curtop += obj.offsetTop;
+            } while (obj = obj.offsetParent);
+        return {x: curleft, y: curtop};
+    }
+}
+
+/* get the absolute event position */
+function get_event_pos(e) {
+    if (e.pageX || e.pageY)     {
+        posx = e.pageX;
+        posy = e.pageY;
+    }
+    else if (e.clientX || e.clientY)    {
+        posx = e.clientX + document.body.scrollLeft
+            + document.documentElement.scrollLeft;
+        posy = e.clientY + document.body.scrollTop
+            + document.documentElement.scrollTop;
+    }
+    return {"x": posx, "y": posy};
+}
+
+/* find out what element the event was the event target */
+function get_event_target(e) {
+    var targ = null;
+    if (e.target) 
+        targ = e.target;
+    else if (e.srcElement) 
+        targ = e.srcElement;
+    if (targ.nodeType == 3) // avoid Safari textNode bug
+        targ = targ.parentNode;
+    return targ;
+}
+
+/* get the event position relatave to the event target */
+function get_relative_event_pos(e) {
+    var targ = get_event_target(e);
+    if (targ) {
+        var pxy = findPos(targ);
+        var posxy = get_event_pos(e);
+
+        var rx = posxy.x - pxy.x  - 2;
+        var ry = posxy.y - pxy.y - 2;
+        return {x: rx, y: ry};
+    }
+}
+
+/* move an element to the body to break out of any relative positioning */
+function promote_to_body(obj) {
+    if (obj) {
+        var bodyList = document.getElementsByTagName("body");
+        if (bodyList) {
+            bodyList[0].appendChild(obj);
+        }
+    }
+}
+        
+
+[SlotMap.css]
+div#slot_hover {
+    visibility: hidden;
+    position: absolute;
+    border: 1px solid pink;
+    left: 0;
+    top: 0;
+    z-index: 10;
+    width: 28px;
+    height: 28px;
+    -moz-border-radius: 50%;
+}
+div#slot_zooming {
+    width: 400px;
+    height: 400px;
+    position: absolute;
+    left:0;
+    top:0;
+    z-index:200;
+    text-align: center;
+    background-color: white;
+    overflow: hidden;
+    opacity: 0.5;
+    -moz-opacity: 0.5;
+    display: none;
+}
+div#slot_zooming p {
+    margin: 0;
+    padding: 140px 0 0 0;
+}
+div#slot_controls {
+    font-size: 0.8em;
+    float: left;
+    position: relative;
+    left: 0px;
+    top: 11px;
+    z-index: 1;
+}
+
+div#slot_panleft {
+    float: left;
+    background: url(resource?name=pan-left.png) scroll no-repeat center;
+    width: 18px;
+    height: 0px;
+}
+div#slot_panright {
+    float: left;
+    background: url(resource?name=pan-right.png) scroll no-repeat center;
+    width: 18px;
+    height: 0px;
+}
+div#slot_panup {
+    clear: both;
+    background: url(resource?name=pan-up.png) scroll no-repeat center;
+    height: 18px;
+    width: 0px;
+    position: relative;
+    left: 18px;
+    z-index:0;
+}
+div#slot_pandown {
+    clear: left;
+    background: url(resource?name=pan-down.png) scroll no-repeat center;
+    height: 18px;
+    width: 0px;
+    position: relative;
+    left: 18px;
+}
+
+div.slot_map {
+    background-color: white;
+    border: 1px solid #CCCCCC;
+    float: left;
+    height: 0px;
+    overflow: hidden;
+    position:relative;
+    width: 0px;
+}
+div#slot_png {
+    clip: rect(0 400px 400px 0);
+    position:absolute;
+    z-index: 0;
+}
+div#slot_glass {
+    height: 0px;
+    left: 0px;
+    position:absolute;
+    top: 0px;
+    width: 0px;
+    z-index: 100;
+}
+div#slot_visualization {
+    position: relative;
+    visibility: hidden;
+}
+div.zoom_node {
+    background-color: white;
+    position: absolute;
+    left: -4px;
+    top: -8px;
+    color: #0066CC;
+}
+div.zoom_node_last {
+    background-color: white;
+    position: absolute;
+    left: 2px;
+    top: -8px;
+    color: #0066CC;
+}
+div.zoom_first {
+    width: 6px;
+    height: 15px;
+    border-bottom: 1px solid black;
+    border-left: 1px solid black;
+    float: left;
+    position: relative;
+    margin-left: 0.5em;
+    cursor: pointer;
+}
+div.zoom_last {
+    width: 6px;
+    height: 15px;
+    border-bottom: 1px solid black;
+    border-right: 1px solid black;
+    float: left;
+    position: relative;
+    margin-right: 0.5em;
+    cursor: pointer;
+}
+div.zoom_middle_right {
+    width: 6px;
+    height: 15px;
+    border-bottom: 1px solid black;
+    border-left: 1px solid black;
+    float: left;
+    position: relative;
+    cursor: pointer;
+}
+div.zoom_middle_left {
+    width: 6px;
+    height: 15px;
+    border-bottom: 1px solid black;
+    float: left;
+    cursor: pointer;
+}
+div#zoom_text {
+    margin-right: 1em;
+    float:left;
+}
+div#zoom_levels {
+    position:relative;
+    float: left;
+}
+div#zoom_pos {
+    background: url(slots.png?dot=Busy) scroll no-repeat center;
+    width: 12px;
+    height: 12px;
+    position: absolute;
+    top: 10px;
+    z-index: 4;
+}
+
+[SlotMap.html]
+<div id="slot_visualization">
+    <h2>{title}</h2>
+    <div id="slot_controls">
+        <div id="zoom_text">Zoom</div><div id="zoom_levels"><div id="zoom_pos"></div></div><div style="clear:left;"><!-- --></div>
+    </div>
+    
+    <div id="slot_panup" onclick="vis.pan_up()"></div>
+    <div id="slot_panleft" onclick="vis.pan_left()"></div>
+    <div class="slot_map" id="{id}">
+        <div id="slot_glass"><!-- mouse target to prevent selecting/dragging image --></div>
+        <div id="slot_png">
+            <img name="{id}" src="{href}" border="0" onload="vis.img_loaded(this)" onerror="vis.img_error(this)" alt="slots" />
+        </div>
+        <div id="slot_hover"><!-- red border around current slot --></div>
+        <div id="slot_zooming"><p>Zooming...</p></div>
+    </div>
+    <div id="slot_panright" onclick="vis.pan_right()"><!-- --></div>
+    <div id="slot_pandown" onclick="vis.pan_down()"></div>
+    {slot_legend}
+</div>
+{slot_info}
+{please_wait}
+<script type="text/javascript">
+    var slot_current_id = "{id}";
+    var show_slot_job_url = "{slot_job_url}";
+    var slot_job_index = "{job_index_param}";
+    var slot_map_info = {size: 0, width: 0, height: 0, count: 0, rows: 0, cols: 0};
+    var slot_clip_size = {slot_clip_size};
+    var oGlass = document.getElementById("slot_glass");
+    if (oGlass) {
+        oGlass.onmousedown = vis.downGlass;
+        oGlass.onmouseup   = vis.upGlass;
+        oGlass.onmousemove = vis.moveGlass;
+        oGlass.onmouseout  = vis.outGlass;
+        oGlass.ondblclick = clicks.doMouseDown;
+        oGlass.onclick    = clicks.doMouseDown;
+        oGlass.dragging = false;
+        oGlass.down_pos = null;
+    }
+</script>
+
+[PleaseWait.javascript]
+function cancel_wait() {
+    var oGlass = document.getElementById("modal_glass");
+    var oWait = document.getElementById("please_wait");
+    if (oGlass && oGlass) {
+        oGlass.style.display = "none";
+        oWait.style.display = "none";
+    }
+    window.location.href = window.location.href;
+    return false;
+}
+function show_wait() {
+    var oGlass = document.getElementById("modal_glass");
+    var oWait = document.getElementById("please_wait");
+    if (oWait && oGlass) {
+        oGlass.style.width = document.body.offsetWidth + "px";
+        oGlass.style.height = document.body.offsetHeight + "px";
+        oGlass.style.display = "block";
+        oWait.style.visibility = "hidden";
+        oWait.style.display = "block";
+
+        promote_to_body(oGlass); // so it covers the entire page
+        promote_to_body(oWait);  // so it can be centered on the page
+        
+        var cp = get_center_point();
+        oWait.style.left = (cp.x - (oWait.offsetWidth / 2)) + "px";
+        oWait.style.top = (cp.y - (oWait.offsetHeight / 2)) + "px";
+        oWait.style.visibility = "visible";
+    }
+}
+function get_center_point()
+{
+    var x = 0;
+    var y = 0;
+
+    var scrollx = (document.documentElement.scrollLeft) ? document.documentElement.scrollLeft : document.body.scrollLeft;
+    var scrolly = (document.documentElement.scrollTop) ? document.documentElement.scrollTop : document.body.scrollTop;
+
+    var width = document.body.offsetWidth;
+    var height = document.body.offsetHeight;
+    
+    return { x: (width + scrollx) / 2, y: (height + scrolly) / 2 };    
+}
+
+    
+[PleaseWait.css]
+div#modal_glass {
+    background-color: black;
+    opacity: .2;
+    -moz-opacity:.2;
+    position: absolute;
+    width: 1px;
+    height: 1px;
+    left: 0;
+    top: 0;
+    display: none;
+    z-index: 200;
+}
+div#please_wait {
+    position: absolute;
+    display: none;
+    z-index: 201;
+    left: 100px;
+    top: 100px;
+}
+div#please_wait form.mform {
+    width: 20em;
+}
+div#please_wait form.mform div.body, div#please_wait form.mform div.foot {
+    text-align: center;
+}
+
+[PleaseWait.html]
+<div id="modal_glass" onclick="cancel_wait()"><!-- --></div>
+<div id="please_wait">
+    <form class="mform">
+      <div class="head">
+        <h1>Loading Job</h1>
+      </div>
+      <div class="body">
+        Loading Job. Please wait...        
+      </div>
+      <div class="foot">
+        {cancel}
+      </div>
+    </form>
+</div>
+
+
+[SlotInfo.css]
+div.slot_info {
+    position: absolute;
+    top: 0;
+    left: 0.5em;
+    visibility: hidden;
+    z-index: 101;
+}
+
+div.slot_container {
+    position: absolute;
+    background-color: #ffffaa;
+    background-image: url(resource?name=shade.png); 
+    background-position: bottom left;
+    background-repeat: repeat-x;
+    border: 1px solid #cccc99;
+    padding: 1em;
+    z-index: 101;
+}
+
+td.slot_info_title {
+    font-weight: bold;
+    height: 1.1em;
+    text-align: right;
+    padding-right: 1em;
+}
+td.slot_info_value {
+    font-weight: normal;
+    height: 1.1em;
+}
+
+html>body .outerpair1 {
+background: url(resource?name=upperrightfade.png) right top no-repeat;
+}
+
+html>body .outerpair2 {
+background: url(resource?name=lowerleftfade.png) left bottom no-repeat;
+padding-top: 8px;
+padding-left: 8px;
+}
+
+html>body .shadowbox {
+background: url(resource?name=shadow.png) bottom right;
+}
+
+html>body .innerbox {
+position: relative;
+left: -8px;
+top: -8px;
+}
+tr.hidden_row {
+    display: none; 
+}
+
+[SlotInfo.html]
+<div id="{id}"><!-- place holder to receive backgound update of slot info on mouseover of a slot --></div>
+<script type="text/javascript">
+    var slot_info_url = "{slot_info_url}";
+    var slot_info_index = "{slot_info_index}";
+    var slot_info_id = "{id}";
+</script>
+
+[SlotInfo.bg_html]
+<div class="outerpair1 slot_info" id="{id}">
+<div class="outerpair2">
+<div class="shadowbox">
+<div class="innerbox slot_container">
+    <table cellspacing="0" cellpadding="0" border="0">
+    {items}
+    </table>
+</div></div></div></div>
+
+[SlotInfo.item_html]
+    <tr {row_class}><td class="slot_info_title">{title}</td>
+        <td {job_id} class="slot_info_value">{value}</td></tr>
+
+[SlotLegend.css]
+div.slot_legend {
+    margin-top: 1em;
+}
+div.slot_states, div.slot_activities {
+    float: left;
+    margin-left: 2em;
+}
+div.slot_states ul, div.slot_activities ul {
+    margin-top: 0.5em;
+    margin-left: 0.5em;
+    font-size: 0.8em;
+}
+div.slot_states ul li span {
+    font-weight: bold;
+}
+
+[SlotLegend.html]
+<div class="slot_legend">
+    {slot_states}
+    {slot_activities}
+    <div style="clear:both"><!-- --></div>
+</div>
+
+[SlotStates.html]
+    <div class="slot_states">
+        <h3>States</h3>
+        <ul>
+        {items}
+        </ul>
+    </div>
+
+[SlotActivities.html]
+    <div class="slot_activities">
+        <h3>Activities</h3>
+        <ul>
+        {items}
+        </ul>
+    </div>
+
+[SlotStates.item_html]
+    <li><span>{initial}</span> {title}</li>
+    
+[SlotActivities.item_html]
+    <li><img src="{href}" width="{dot_size}" height="{dot_size}" alt="{title}"/> {title}</li>    
+    
\ No newline at end of file




More information about the rhmessaging-commits mailing list