#1623 JS: slider functionality missing

jessevdam Thu 25 Aug 2011

I noticed that the actual slider functionality is not yet implemented in the sashpane, so I made a small start. Here is the code that works for a vertical splitter tested it with only to childs in the main window.

fan.fwt.SashPane.prototype.doHoriz = function()
{
var w  = this.m_size.m_w;
var h  = this.m_size.m_h;
var wt = this.m_weights;

var dx = 0;
var dw = Math.floor(w / this.m_kids.size());

var sizes = [];
var positions = [];
for (var i=0; i<this.m_kids.size(); i++)
{
  var cw = wt==null ? dw : Math.floor(w * (wt.get(i).valueOf() / 100));
  var ch = h;

  // if last widget, force to fill remaining space
  if (i == this.m_kids.size()-1)
    cw = w-dx;
  sizes[i] = cw;
  positions[i] = dx;
  dx += cw;
}

for (var i=0; i<this.m_kids.size(); i++)
{
  var cw = sizes[i];
  var cx = positions[i];
  var ch = h;

  // if last widget, force to fill remaining space
  var lastWidget = i == this.m_kids.size()-1

  this.m_kids.get(i).pos$(fan.gfx.Point.make(cx + (i == 0 ? 0 : 3), 0));
  this.m_kids.get(i).size$(fan.gfx.Size.make(cw - (i == 0 || lastWidget ? 3 : 6), ch));

  if(!lastWidget)
  {
    var sliderDiv = null;
    if(i >= this.m_slider.length)
    {
      sliderDiv = this.emptyDiv();
      sliderDiv.isSlider = true;
      sliderDiv.style.backgroundColor = "darkgrey";
      sliderDiv.style.cursor = "col-resize";

      var startPointX = -1;
      var sliderOrigX = -1;
      var $this = this;
      var $i = i;
      var moverDiv = this.emptyDiv();        
      var mouseUp = function(e)
      {
        $this.elem.removeChild(moverDiv);
        e.stopPropagation();
        e.preventDefault();
      }  
      var mouseMove = function(e)
      {
        var div = e.clientX - startPointX;
        var x = sliderOrigX + div + 3;
        var temp = (x - sliderDiv.startSpace) / sliderDiv.endSpace;
        wt.set($i,new Number(sliderDiv.percentage * temp * 100));
        wt.set($i + 1,new Number(sliderDiv.percentage * (1 - temp) * 100));
        $this.relayout();
        e.stopPropagation();
        e.preventDefault();
      }          
      moverDiv.addEventListener("mouseup",mouseUp,false);
      moverDiv.addEventListener("mousemove",mouseMove,false);

      var mouseDown = function(e)
      {
        startPointX = e.clientX;
        sliderOrigX = sliderDiv.x;
        with(moverDiv.style)
        {
          left    = $this.m_parent.elem.style.left;
          top     = $this.m_parent.elem.style.top;
          width   = $this.m_parent.elem.style.width;
          height  = $this.m_parent.elem.style.height;        
          backgroundColor = "darkgrey";
          opacity = 0.1; //ah we get that nice effect for free :)           
        }
        $this.elem.appendChild(moverDiv);
        e.stopPropagation();
        e.preventDefault();
      }

      sliderDiv.addEventListener("mousedown",mouseDown,false);
      this.m_slider[i] = sliderDiv
      this.elem.appendChild(sliderDiv)        
    }
    else
    {
      sliderDiv = this.m_slider[i]
    }
    sliderDiv.x = (cx + cw - 3);
    sliderDiv.startSpace = cx;
    sliderDiv.endSpace = cx + cw + sizes[i + 1];
    sliderDiv.percentage = (wt.get(i).valueOf() + wt.get(i + 1).valueOf()) / 100;
    with(sliderDiv.style)
    {
      left    = sliderDiv.x + "px";
      top     = 0  + "px";
      width   = 6 + "px";
      height  = ch + "px";              
    }
  }
}
}

andy Thu 25 Aug 2011

Thanks - will take a look.

jessevdam Thu 25 Aug 2011

I made some adjustments, now it works for vertical ones as well as well it is working for inner widgets. It should also work for more then 2 childs, but there is no code, which prevents you from scrolling out of the range and I did not test it.

fan.fwt.SashPane.prototype.sync = function()
{
if (this.m_weights != null && this.m_weights.size() != this.m_kids.size())
  throw fan.sys.ArgErr.make("weights.size != kids.size");

var horizontal = this.m_orientation == fan.gfx.Orientation.m_horizontal;
var w  = horizontal ? this.m_size.m_w : this.m_size.m_h;
var h  = horizontal ? this.m_size.m_h : this.m_size.m_w;
var wt = this.m_weights;

var dx = 0;
var dw = Math.floor(w / this.m_kids.size());

var sizes = [];
var positions = [];
for (var i=0; i<this.m_kids.size(); i++)
{
  var cw = wt==null ? dw : Math.floor(w * (wt.get(i).valueOf() / 100));
  var ch = h;

  // if last widget, force to fill remaining space
  if (i == this.m_kids.size()-1)
    cw = w-dx;
  sizes[i] = cw;
  positions[i] = dx;
  dx += cw;
}

for (var i=0; i<this.m_kids.size(); i++)
{
  var cw = sizes[i];
  var cx = positions[i];
  var ch = h;

  // if last widget, force to fill remaining space
  var lastWidget = i == this.m_kids.size()-1

  if(horizontal)
  {
    this.m_kids.get(i).pos$(fan.gfx.Point.make(cx + (i == 0 ? 0 : 3), 0));
    this.m_kids.get(i).size$(fan.gfx.Size.make(cw - (i == 0 || lastWidget ? 3 : 6), ch));
  }
  else
  {
    this.m_kids.get(i).pos$(fan.gfx.Point.make(0,cx + (i == 0 ? 0 : 3)));
    this.m_kids.get(i).size$(fan.gfx.Size.make(ch,cw - (i == 0 || lastWidget ? 3 : 6)));
  }

  if(!lastWidget)
  {
    var sliderDiv = null;
    if(i >= this.m_slider.length)
    {
      sliderDiv = this.emptyDiv();
      sliderDiv.isSlider = true;
      sliderDiv.style.backgroundColor = "darkgrey";
      sliderDiv.style.cursor = horizontal ? "col-resize" : "row-resize";

      var startPointX = -1;
      var sliderOrigX = -1;
      var $this = this;
      var $i = i;
      var moverDiv = this.emptyDiv();        
      var mouseUp = function(e)
      {
        $this.elem.removeChild(moverDiv);
        e.stopPropagation();
        e.preventDefault();
      }  
      var mouseMove = function(e)
      {
        var div = (horizontal ? e.clientX : e.clientY) - startPointX;
        var x = sliderOrigX + div + 3;
        var temp = (x - sliderDiv.startSpace) / sliderDiv.endSpace;
        wt.set($i,new Number(sliderDiv.percentage * temp * 100));
        wt.set($i + 1,new Number(sliderDiv.percentage * (1 - temp) * 100));
        $this.relayout();
        e.stopPropagation();
        e.preventDefault();
      }          
      moverDiv.addEventListener("mouseup",mouseUp,false);
      moverDiv.addEventListener("mousemove",mouseMove,false);

      var mouseDown = function(e)
      {
        startPointX = horizontal ? e.clientX : e.clientY;
        sliderOrigX = sliderDiv.x;
        with(moverDiv.style)
        {
          width   = $this.m_parent.elem.style.width;
          height  = $this.m_parent.elem.style.height;        
          backgroundColor = "darkgrey";
          opacity = 0.3; //ah we get that nice effect for free :)           
        }
        $this.elem.appendChild(moverDiv);
        e.stopPropagation();
        e.preventDefault();
      }

      sliderDiv.addEventListener("mousedown",mouseDown,false);
      this.m_slider[i] = sliderDiv;
      this.elem.appendChild(sliderDiv);    
    }
    else
    {
      sliderDiv = this.m_slider[i];
    }
    sliderDiv.x = (cx + cw - 3);
    sliderDiv.startSpace = cx;
    sliderDiv.endSpace = cx + cw + sizes[i + 1];
    sliderDiv.percentage = (wt.get(i).valueOf() + wt.get(i + 1).valueOf()) / 100;
    with(sliderDiv.style)
    {
      if(horizontal)
      {
        left    = sliderDiv.x + "px";
        top     = 0  + "px";
        width   = 6 + "px";
        height  = ch + "px";
      }
      else
      {
        top     = sliderDiv.x + "px";
        left    = 0  + "px";
        height  = 6 + "px";
        width   = ch + "px";            
      }
    }
  }
}
fan.fwt.Widget.prototype.sync.call(this);
}

Login or Signup to reply.