jspaint/$Component.js

111 lines
2.4 KiB
JavaScript

function $Component(name, orientation, $el){
//a draggable widget that can be undocked into a window
var $c = $(E("div")).addClass("jspaint-component");
$c.addClass("jspaint-"+name+"-component");
$c.append($el);
$c.appendTo({
tall: $left,
wide: $bottom,
}[orientation]);
var ox, oy, w, h, pos, pos_axis;
var dragging = false;
var $dock_to;
var $ghost;
$c.on("mousedown", function(e){
if(e.button !== 0) return;
var rect = $c[0].getBoundingClientRect();
w = (~~(rect.width/2))*2 + 1; //make sure these dimensions are odd numbers
h = (~~(rect.height/2))*2 + 1;
ox = $c.position().left - e.clientX;
oy = $c.position().top - e.clientY;
dragging = true;
if(!$ghost){
$ghost = $(E("div")).addClass("jspaint-component-ghost dock");
$ghost.css({
position: "absolute",
display: "block",
width: w,
height: h,
left: e.clientX + ox,
top: e.clientY + oy
});
$ghost.appendTo("body");
}
e.preventDefault();
});
$el.on("mousedown", function(e){
return false;
});
$G.on("mousemove", function(e){
if(!dragging) return;
$ghost.css({
left: e.clientX + ox,
top: e.clientY + oy,
});
$dock_to = null;
var ghost_rect = $ghost[0].getBoundingClientRect();
var q = 5;
if(orientation === "tall"){
pos_axis = "top";
if(ghost_rect.left-q < $left[0].getBoundingClientRect().right){
$dock_to = $left;
}
if(ghost_rect.right+q > $right[0].getBoundingClientRect().left){
$dock_to = $right;
}
}else{
pos_axis = "left";
if(ghost_rect.top-q < $top[0].getBoundingClientRect().bottom){
$dock_to = $top;
}
if(ghost_rect.bottom+q > $bottom[0].getBoundingClientRect().top){
$dock_to = $bottom;
}
}
pos = ghost_rect[pos_axis];
if($dock_to){
var dock_to_rect = $dock_to[0].getBoundingClientRect();
pos -= dock_to_rect[pos_axis];
$ghost.addClass("dock");
}else{
$ghost.removeClass("dock");
}
e.preventDefault();
});
$G.on("mouseup", function(e){
if(!dragging) return;
dragging = false;
if($dock_to){
$dock_to.append($c);
pos = Math.max(pos, 0);
if(pos_axis === "top"){
pos = Math.min(pos, $dock_to.height() - $ghost.height());
}else{
pos = Math.min(pos, $dock_to.width() - $ghost.width());
}
$c.css("position", "relative");
$c.css(pos_axis, pos);
}else{
//put component in window
}
$ghost && $ghost.remove(), $ghost = null;
$G.trigger("resize");
});
return $c;
}