# Copyright (c) 2009 Michael Fellinger # # Description: # # When modifying the tiling algorithm, it's useful to see the transitions # between the different states animated. # This is not a default feature of VER, as it can be very resource-intensive. # # Usage: # # Put following line into your rc.rb # VER.plugin :animated_tiling require 'ver/layout/tiling' module VER class TilingLayout module CommonTiling # animates hiding the given +windows+ def apply_hidden(*windows) target = { relheight: 0.0, relwidth: 0.5, relx: 0.5, rely: 1.0 } windows.flatten.each do |window| evolve(window, target){ window.place_forget } end end # animates movement of an +window+ to the position given as +target+ def evolve(window, target) original = window.place_configure if original.is_a?(Hash) o_relh, o_relw, o_relx, o_rely = original.values_at(:relheight, :relwidth, :relx, :rely) else o_relh, o_relw, o_relx, o_rely = 0.0, 0.5, 0.5, 1.0 # return window.place(target) end t_relh, t_relw, t_relx, t_rely = target.values_at(:relheight, :relwidth, :relx, :rely) steps = 50 stepper = lambda{|from, to| from, to = (from * 1000).to_i, (to * 1000).to_i if from > to to.step(from, steps).to_a.reverse elsif to > from from.step(to, steps).to_a else [from] end } padder = lambda{|given, max| unless given.empty? ar = Array.new(max){ given.last } ar[0, given.size] = given ar.map{|e| e / 1000.0 } end } s_relh = stepper[o_relh, t_relh] s_relw = stepper[o_relw, t_relw] s_relx = stepper[o_relx, t_relx] s_rely = stepper[o_rely, t_rely] max = [s_relh, s_relw, s_relx, s_rely].max_by{|a| a.size }.size a_relh = padder[s_relh, max] || Array.new(max){ t_relh } a_relw = padder[s_relw, max] || Array.new(max){ t_relw } a_relx = padder[s_relx, max] || Array.new(max){ t_relx } a_rely = padder[s_rely, max] || Array.new(max){ t_rely } zipped = a_relh.zip(a_relw.zip(a_relx.zip(a_rely))).map{|a| a.flatten } time_per_step = (500 / zipped.size) zipped.each_with_index do |(h, w, x, y), i| Tk::After.ms(i * time_per_step) do window.place(relx: x, rely: y, relheight: h, relwidth: w) end end Tk::After.ms((zipped.size + 1) * time_per_step) do window.place(target) yield if block_given? end end end end end