Class: Rumai::View

Inherits:
WidgetNode show all
Includes:
Enumerable, Chain, ClientContainer, WidgetImpl
Defined in:
lib/rumai/wm.rb

Overview

The visualization of a tag.

Instance Attribute Summary

Attributes included from WidgetImpl

#id

Attributes inherited from Node

#path

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ClientContainer

#clients, #grouping

Methods included from Chain

#next, #prev

Methods included from WidgetImpl

#==, #current?

Methods inherited from Node

#[], #children, #clear, #create, #directory?, #each_line, #entries, #exist?, #method_missing, #open, #parent, #read, #remove, #stat, #write

Methods included from ExportInstanceMethods

extended

Constructor Details

#initialize(view_id) ⇒ View

Returns a new instance of View.



749
750
751
# File 'lib/rumai/wm.rb', line 749

def initialize view_id
  super view_id, '/tag'
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Rumai::Node

Class Method Details

.currObject

Returns the currently focused view.



760
761
762
# File 'lib/rumai/wm.rb', line 760

def self.curr
  new FOCUSED_WIDGET_ID
end

Instance Method Details

#area_idsObject

Returns the IDs of all areas in this view.



847
848
849
# File 'lib/rumai/wm.rb', line 847

def area_ids
  manifest.scan(/^# (\d+) /).flatten.unshift(FLOATING_AREA_ID)
end

#area_of_client(client_or_id) ⇒ Object

Returns the area which contains the given client in this view.



830
831
832
833
834
835
836
837
838
839
840
841
842
# File 'lib/rumai/wm.rb', line 830

def area_of_client client_or_id
  arg =
    if client_or_id.respond_to? :id
      client_or_id.id
    else
      client_or_id
    end

  manifest =~ /^(\S+) #{arg}/
  if area_id = $1
    Area.new area_id, self
  end
end

#areasObject

Returns all areas in this view.



854
855
856
# File 'lib/rumai/wm.rb', line 854

def areas
  area_ids.map! {|i| Area.new i, self }
end

#arrange_columns(lengths, layout = nil) ⇒ Object

Applies the given length to each column in sequence. Also, the given layout is applied to all columns, if specified.



1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
# File 'lib/rumai/wm.rb', line 1040

def arrange_columns lengths, layout = nil
  maintain_focus do
    i = 0
    each_column do |column|
      if i < lengths.length
        column.length = lengths[i]
        column.layout = layout if layout
        i += 1
      else
        break
      end
    end
  end
end

#chainObject

Returns a list of all views.



778
779
780
# File 'lib/rumai/wm.rb', line 778

def chain
  Rumai.views
end

#client_ids(area_id = '\S+') ⇒ Object

Returns the IDs of the clients contained in the given area within this view.



790
791
792
# File 'lib/rumai/wm.rb', line 790

def client_ids area_id = '\S+'
  manifest.scan(/^#{area_id} (0x\S+)/).flatten
end

#columnsObject Also known as: managed_areas

Returns all columns (managed areas) in this view.



868
869
870
# File 'lib/rumai/wm.rb', line 868

def columns
  areas[1..-1]
end

#each(&block) ⇒ Object

Iterates through each area in this view.



801
802
803
# File 'lib/rumai/wm.rb', line 801

def each &block
  areas.each(&block)
end

#each_column(starting_column_id = 1) ⇒ Object Also known as: each_managed_area

Resiliently iterates through possibly destructive changes to each column. That is, if the given block creates new columns, then those will also be processed in the iteration.



879
880
881
882
883
884
885
# File 'lib/rumai/wm.rb', line 879

def each_column starting_column_id = 1
  i = starting_column_id
  while (column = Area.new(i, self)).exist?
    yield column
    i += 1
  end
end

#floating_areaObject

Returns the floating area of this view.



861
862
863
# File 'lib/rumai/wm.rb', line 861

def floating_area
  Area.floating self
end

#focusObject

Focuses this view.



767
768
769
# File 'lib/rumai/wm.rb', line 767

def focus
  IXP_FS_ROOT.ctl.write "view #{@id}"
end

#grid(max_clients_per_column = nil) ⇒ Object Also known as: arrange_in_grid

Arranges the clients in this view, while maintaining their relative order, in (at best) a square grid.



1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
# File 'lib/rumai/wm.rb', line 1010

def grid max_clients_per_column = nil
  # compute client distribution
  unless max_clients_per_column
    num_clients = num_managed_clients
    return unless num_clients > 0

    num_columns = Math.sqrt(num_clients)
    max_clients_per_column = (num_clients / num_columns).round
  end

  return if max_clients_per_column < 1

  # apply the distribution
  maintain_focus do
    each_column do |a|
      a.length = max_clients_per_column
      a.layout = :default
    end
  end
end

#manifestObject

Returns the manifest of all areas and clients in this view.



812
813
814
# File 'lib/rumai/wm.rb', line 812

def manifest
  index.read || ''
end

#select(direction) ⇒ Object

Moves the focus from the current client in the given direction.



819
820
821
# File 'lib/rumai/wm.rb', line 819

def select direction
  ctl.write "select #{direction}"
end

#stack(num_columns = 2) ⇒ Object Also known as: arrange_in_stacks

Arranges the clients in this view, while maintaining their relative order, in the given number of columns.



1000
1001
1002
1003
1004
# File 'lib/rumai/wm.rb', line 1000

def stack num_columns = 2
  heights = [num_managed_clients / num_columns] * num_columns
  heights[-1] += num_managed_clients % num_columns
  arrange_columns heights, :stack
end

#tile_inwardObject Also known as: arrange_in_diamond

Arranges columns with the following number of clients in them:

1, 2, 3, …, 3, 2, 1

Imagine two equilateral triangles with their bases on the left and right sides of the screen and their peaks meeting in the middle of the screen.



949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
# File 'lib/rumai/wm.rb', line 949

def tile_inward
  rising, num_summit_clients, falling = calculate_equilateral_triangle

  # distribute extra clients in the middle
  summit = []
  if num_summit_clients > 0
    split = num_summit_clients / 2
    carry = num_summit_clients % 2
    summit = [split, carry, split].reject(&:zero?)

    # one client per column cannot be considered as "tiling" so squeeze
    # these singular columns together to create one giant middle column
    if summit.length == num_summit_clients
      summit = [num_summit_clients]
    end
  end

  arrange_columns rising + summit + falling, :default
end

#tile_leftObject

Arranges columns with the following number of clients in them:

N, 1



922
923
924
# File 'lib/rumai/wm.rb', line 922

def tile_left
  arrange_columns [num_managed_clients-1, 1], :default
end

#tile_leftwardObject

Arranges columns with the following number of clients in them:

…, 3, 2, 1

Imagine an equilateral triangle with its base on the left side of the screen and its peak on the right side of the screen.



935
936
937
938
939
# File 'lib/rumai/wm.rb', line 935

def tile_leftward
  num_rising_columns, num_summit_clients = calculate_right_triangle
  heights = (1..num_rising_columns).to_a.push(num_summit_clients).reverse
  arrange_columns heights, :default
end

#tile_outwardObject

Arranges columns with the following number of clients in them:

…, 3, 2, 1, 2, 3, …

Imagine two equilateral triangles with their bases meeting in the middle of the screen and their peaks reaching outward to the left and right sides of the screen.



978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
# File 'lib/rumai/wm.rb', line 978

def tile_outward
  rising, num_summit_clients, falling = calculate_equilateral_triangle
  heights = falling + rising[1..-1]

  # distribute extra clients on the outsides
  num_summit_clients += rising[0].to_i
  if num_summit_clients > 0
    split = num_summit_clients / 2
    carry = num_summit_clients % 2
    # put the remainder on the left side to minimize the need for
    # rearrangement when clients are removed or added to the view
    heights.unshift split + carry
    heights.push split
  end

  arrange_columns heights, :default
end

#tile_rightObject Also known as: arrange_as_larswm

Arranges columns with the following number of clients in them:

1, N



898
899
900
# File 'lib/rumai/wm.rb', line 898

def tile_right
  arrange_columns [1, num_managed_clients-1], :default
end

#tile_rightwardObject

Arranges columns with the following number of clients in them:

1, 2, 3, …

Imagine an equilateral triangle with its base on the right side of the screen and its peak on the left side of the screen.



911
912
913
914
915
# File 'lib/rumai/wm.rb', line 911

def tile_rightward
  num_rising_columns, num_summit_clients = calculate_right_triangle
  heights = (1..num_rising_columns).to_a.push(num_summit_clients)
  arrange_columns heights, :default
end