uh-layout 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +7 -0
- data/lib/uh/layout/arrangers/fixed_width.rb +30 -0
- data/lib/uh/layout/arrangers/stack.rb +24 -0
- data/lib/uh/layout/arrangers/vert_tile.rb +28 -0
- data/lib/uh/layout/client_column_mover.rb +33 -0
- data/lib/uh/layout/column.rb +20 -10
- data/lib/uh/layout/container.rb +4 -3
- data/lib/uh/layout/tag.rb +11 -0
- data/lib/uh/layout/version.rb +1 -1
- data/lib/uh/layout.rb +26 -18
- data/spec/support/factories.rb +14 -0
- data/spec/uh/layout/arrangers/fixed_width_spec.rb +72 -0
- data/spec/uh/layout/arrangers/stack_spec.rb +42 -0
- data/spec/uh/layout/arrangers/vert_tile_spec.rb +49 -0
- data/spec/uh/layout/client_column_mover_spec.rb +96 -0
- data/spec/uh/layout/column_spec.rb +52 -12
- data/spec/uh/layout/container_spec.rb +5 -5
- data/spec/uh/layout/screen_spec.rb +1 -1
- data/spec/uh/layout/tag_spec.rb +32 -3
- data/spec/uh/layout_spec.rb +39 -34
- data/uh-layout.gemspec +1 -2
- metadata +20 -12
- data/Gemfile-custom.rb +0 -7
- data/lib/uh/layout/column/arranger.rb +0 -66
- data/lib/uh/layout/geo_accessors.rb +0 -10
- data/spec/uh/layout/column/arranger_spec.rb +0 -181
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 47a100f2229b06ab1aa01eeb35e1b8baba73f804
|
4
|
+
data.tar.gz: 3cc639552ca1d7cfa766a0d6afb03dab85532b86
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2c0c3f914c932e129fb9eaf10c18a6fe7cc90335adec8f4822aecda6a6856204ceff06e832016d59716de7b08506450f49b0c56c36b53198d6e29bce3a31f621
|
7
|
+
data.tar.gz: 8a7ce44e77e6edad1746dc478253a0a742c404538e0b9d771e605ad67a6ecc6c19843a1f984cdec1ed4841d697a467574134aa6568d7105edcbe726f7943328c
|
data/.gitignore
CHANGED
data/.travis.yml
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
module Uh
|
2
|
+
class Layout
|
3
|
+
module Arrangers
|
4
|
+
class FixedWidth
|
5
|
+
DEFAULT_WIDTH = 484
|
6
|
+
|
7
|
+
def initialize(entries, geo, width: DEFAULT_WIDTH)
|
8
|
+
@entries = entries
|
9
|
+
@geo = geo
|
10
|
+
@width = width
|
11
|
+
end
|
12
|
+
|
13
|
+
def arrange
|
14
|
+
return if @entries.empty?
|
15
|
+
@entries.each_with_index do |column, i|
|
16
|
+
column.x = @width * i + @geo.x
|
17
|
+
column.y = @geo.y
|
18
|
+
column.width = @width
|
19
|
+
column.height = @geo.height
|
20
|
+
end
|
21
|
+
@entries.last.width = @geo.width - (@entries.last.x - @geo.x)
|
22
|
+
end
|
23
|
+
|
24
|
+
def max_count?
|
25
|
+
(@geo.width / (@entries.size + 1)) < @width
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Uh
|
2
|
+
class Layout
|
3
|
+
module Arrangers
|
4
|
+
class Stack
|
5
|
+
def initialize(entries, geo)
|
6
|
+
@entries = entries
|
7
|
+
@geo = geo
|
8
|
+
end
|
9
|
+
|
10
|
+
def arrange
|
11
|
+
@entries.each { |e| e.geo = @geo.dup }
|
12
|
+
end
|
13
|
+
|
14
|
+
def each_visible
|
15
|
+
yield @entries.current if @entries.current
|
16
|
+
end
|
17
|
+
|
18
|
+
def each_hidden
|
19
|
+
([*@entries] - [@entries.current]).each { |e| yield e }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Uh
|
2
|
+
class Layout
|
3
|
+
module Arrangers
|
4
|
+
class VertTile
|
5
|
+
def initialize(entries, geo)
|
6
|
+
@entries = entries
|
7
|
+
@geo = geo
|
8
|
+
end
|
9
|
+
|
10
|
+
def arrange
|
11
|
+
entry_height = @geo.height / @entries.size - 1
|
12
|
+
@entries.each_with_index do |entry, i|
|
13
|
+
entry.geo = @geo.dup
|
14
|
+
entry.y = (entry_height + 1) * i
|
15
|
+
entry.height = entry_height
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def each_visible
|
20
|
+
@entries.each { |e| yield e }
|
21
|
+
end
|
22
|
+
|
23
|
+
def each_hidden
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Uh
|
2
|
+
class Layout
|
3
|
+
class ClientColumnMover
|
4
|
+
def initialize(columns, columns_max_count)
|
5
|
+
@columns = columns
|
6
|
+
@columns_max_count = columns_max_count
|
7
|
+
end
|
8
|
+
|
9
|
+
def move_current(direction)
|
10
|
+
@columns.current.remove client = @columns.current.current_client
|
11
|
+
dest_column = get_or_create_column direction
|
12
|
+
dest_column << client
|
13
|
+
dest_column.current_client = client
|
14
|
+
@columns.current = dest_column
|
15
|
+
end
|
16
|
+
|
17
|
+
def get_or_create_column(direction)
|
18
|
+
if candidate = @columns.get(direction)
|
19
|
+
candidate
|
20
|
+
elsif @columns_max_count
|
21
|
+
@columns.get direction, cycle: true
|
22
|
+
else
|
23
|
+
Column.new(Geo.new).tap do |o|
|
24
|
+
case direction
|
25
|
+
when :pred then @columns.unshift o
|
26
|
+
when :succ then @columns << o
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/uh/layout/column.rb
CHANGED
@@ -1,6 +1,11 @@
|
|
1
1
|
module Uh
|
2
2
|
class Layout
|
3
3
|
class Column
|
4
|
+
MODES = {
|
5
|
+
stack: Arrangers::Stack,
|
6
|
+
tile: Arrangers::VertTile
|
7
|
+
}.freeze
|
8
|
+
|
4
9
|
include GeoAccessors
|
5
10
|
|
6
11
|
extend Forwardable
|
@@ -9,11 +14,12 @@ module Uh
|
|
9
14
|
def_delegator :@clients, :current=, :current_client=
|
10
15
|
def_delegator :current_client, :==, :current_client?
|
11
16
|
|
12
|
-
attr_reader :geo, :clients
|
17
|
+
attr_reader :geo, :clients, :mode
|
13
18
|
|
14
19
|
def initialize(geo)
|
15
20
|
@geo = geo.dup
|
16
21
|
@clients = Container.new
|
22
|
+
@mode = :stack
|
17
23
|
end
|
18
24
|
|
19
25
|
def to_s
|
@@ -26,18 +32,22 @@ module Uh
|
|
26
32
|
self
|
27
33
|
end
|
28
34
|
|
35
|
+
def mode_toggle
|
36
|
+
@mode = MODES.keys[(MODES.keys.index(@mode) + 1) % MODES.keys.size]
|
37
|
+
end
|
38
|
+
|
39
|
+
def arranger
|
40
|
+
MODES[@mode].new @clients, @geo
|
41
|
+
end
|
42
|
+
|
29
43
|
def arrange_clients
|
30
|
-
|
31
|
-
|
32
|
-
client.moveresize
|
33
|
-
end
|
44
|
+
arranger.arrange
|
45
|
+
clients.each &:moveresize
|
34
46
|
end
|
35
47
|
|
36
|
-
def show_hide_clients
|
37
|
-
|
38
|
-
|
39
|
-
end
|
40
|
-
@clients.current.show if @clients.current && @clients.current.hidden?
|
48
|
+
def show_hide_clients(arranger: self.arranger)
|
49
|
+
arranger.each_visible { |client| client.show if client.hidden? }
|
50
|
+
arranger.each_hidden { |client| client.hide unless client.hidden? }
|
41
51
|
end
|
42
52
|
end
|
43
53
|
end
|
data/lib/uh/layout/container.rb
CHANGED
@@ -4,8 +4,8 @@ module Uh
|
|
4
4
|
include Enumerable
|
5
5
|
|
6
6
|
extend Forwardable
|
7
|
-
def_delegators :@entries, :<<, :[], :each, :empty?, :
|
8
|
-
:size, :unshift
|
7
|
+
def_delegators :@entries, :<<, :[], :each, :empty?, :fetch, :first,
|
8
|
+
:index, :last, :size, :unshift
|
9
9
|
|
10
10
|
def initialize(entries = [])
|
11
11
|
@entries = entries
|
@@ -19,7 +19,8 @@ module Uh
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def current=(entry)
|
22
|
-
|
22
|
+
fail ArgumentError, 'unknown entry' unless include? entry
|
23
|
+
@current_index = @entries.index entry
|
23
24
|
end
|
24
25
|
|
25
26
|
def remove(entry)
|
data/lib/uh/layout/tag.rb
CHANGED
@@ -9,6 +9,7 @@ module Uh
|
|
9
9
|
def_delegator :@columns, :each, :each_column
|
10
10
|
def_delegator :current_column, :==, :current_column?
|
11
11
|
def_delegator :clients, :each, :each_client
|
12
|
+
def_delegator :arranger, :max_count?, :columns_max_count?
|
12
13
|
|
13
14
|
attr_reader :id, :geo, :columns
|
14
15
|
|
@@ -39,6 +40,16 @@ module Uh
|
|
39
40
|
end
|
40
41
|
end
|
41
42
|
|
43
|
+
def arranger
|
44
|
+
Arrangers::FixedWidth.new(@columns, @geo)
|
45
|
+
end
|
46
|
+
|
47
|
+
def arrange_columns
|
48
|
+
@columns.remove_if &:empty?
|
49
|
+
arranger.arrange
|
50
|
+
@columns.each &:arrange_clients
|
51
|
+
end
|
52
|
+
|
42
53
|
def hide
|
43
54
|
clients.each &:hide
|
44
55
|
end
|
data/lib/uh/layout/version.rb
CHANGED
data/lib/uh/layout.rb
CHANGED
@@ -1,16 +1,21 @@
|
|
1
1
|
require 'forwardable'
|
2
2
|
|
3
|
-
require 'uh/layout/
|
3
|
+
require 'uh/layout/arrangers/fixed_width'
|
4
|
+
require 'uh/layout/arrangers/stack'
|
5
|
+
require 'uh/layout/arrangers/vert_tile'
|
4
6
|
require 'uh/layout/bar'
|
7
|
+
require 'uh/layout/client_column_mover'
|
5
8
|
require 'uh/layout/container'
|
6
9
|
require 'uh/layout/column'
|
7
|
-
require 'uh/layout/column/arranger'
|
8
10
|
require 'uh/layout/dumper'
|
9
11
|
require 'uh/layout/screen'
|
10
12
|
require 'uh/layout/tag'
|
11
13
|
|
12
14
|
module Uh
|
13
15
|
class Layout
|
16
|
+
Error = Class.new(StandardError)
|
17
|
+
ArgumentError = Class.new(Error)
|
18
|
+
|
14
19
|
extend Forwardable
|
15
20
|
def_delegator :@screens, :current, :current_screen
|
16
21
|
def_delegator :current_screen, :==, :current_screen?
|
@@ -36,10 +41,6 @@ module Uh
|
|
36
41
|
screens.any? { |screen| screen.include? client }
|
37
42
|
end
|
38
43
|
|
39
|
-
def arranger_for_current_tag
|
40
|
-
Column::Arranger.new(current_tag.columns, current_tag.geo)
|
41
|
-
end
|
42
|
-
|
43
44
|
def update_widgets
|
44
45
|
@widgets.each &:update
|
45
46
|
@widgets.each &:redraw
|
@@ -63,8 +64,7 @@ module Uh
|
|
63
64
|
def remove(client)
|
64
65
|
screen, tag, column = find_client client
|
65
66
|
column.remove client
|
66
|
-
|
67
|
-
tag.each_column &:arrange_clients
|
67
|
+
tag.arrange_columns
|
68
68
|
column.show_hide_clients
|
69
69
|
current_client.focus if current_client
|
70
70
|
update_widgets
|
@@ -94,14 +94,11 @@ module Uh
|
|
94
94
|
|
95
95
|
def handle_tag_set(tag_id)
|
96
96
|
return unless current_client && current_tag.id != tag_id
|
97
|
+
previous_tag_id = current_tag.id
|
97
98
|
remove client = current_client
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
Column::Arranger.new(tag.columns, tag.geo).redraw
|
102
|
-
tag.each_column &:arrange_clients
|
103
|
-
current_client.focus if current_client
|
104
|
-
update_widgets
|
99
|
+
handle_tag_sel tag_id
|
100
|
+
push client
|
101
|
+
handle_tag_sel previous_tag_id
|
105
102
|
end
|
106
103
|
|
107
104
|
def handle_column_sel(direction)
|
@@ -111,6 +108,13 @@ module Uh
|
|
111
108
|
update_widgets
|
112
109
|
end
|
113
110
|
|
111
|
+
def handle_column_mode_toggle
|
112
|
+
return unless current_column
|
113
|
+
current_column.mode_toggle
|
114
|
+
current_column.arrange_clients
|
115
|
+
current_column.show_hide_clients
|
116
|
+
end
|
117
|
+
|
114
118
|
def handle_client_sel(direction)
|
115
119
|
return unless current_client
|
116
120
|
current_column.clients.sel direction
|
@@ -125,10 +129,10 @@ module Uh
|
|
125
129
|
update_widgets
|
126
130
|
end
|
127
131
|
|
128
|
-
def handle_client_column_set(direction,
|
132
|
+
def handle_client_column_set(direction, mover: client_mover_for_current_tag)
|
129
133
|
return unless current_client
|
130
|
-
|
131
|
-
current_tag.
|
134
|
+
mover.move_current direction
|
135
|
+
current_tag.arrange_columns
|
132
136
|
current_tag.each_column &:show_hide_clients
|
133
137
|
update_widgets
|
134
138
|
end
|
@@ -157,5 +161,9 @@ module Uh
|
|
157
161
|
current_screen.tags << tag
|
158
162
|
end
|
159
163
|
end
|
164
|
+
|
165
|
+
def client_mover_for_current_tag
|
166
|
+
ClientColumnMover.new(current_tag.columns, current_tag.columns_max_count?)
|
167
|
+
end
|
160
168
|
end
|
161
169
|
end
|
data/spec/support/factories.rb
CHANGED
@@ -1,8 +1,22 @@
|
|
1
1
|
module Factories
|
2
|
+
class Entry
|
3
|
+
include Uh::GeoAccessors
|
4
|
+
|
5
|
+
attr_accessor :geo
|
6
|
+
|
7
|
+
def initialize(geo)
|
8
|
+
@geo = geo
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
2
12
|
def build_client
|
3
13
|
Uh::WM::Client.new(instance_spy Uh::Window)
|
4
14
|
end
|
5
15
|
|
16
|
+
def build_entry(geo = build_geo)
|
17
|
+
Entry.new(geo)
|
18
|
+
end
|
19
|
+
|
6
20
|
def build_geo(x = 0, y = 0, width = 640, height = 480)
|
7
21
|
Uh::Geo.new(x, y, width, height)
|
8
22
|
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Uh
|
2
|
+
class Layout
|
3
|
+
module Arrangers
|
4
|
+
describe FixedWidth do
|
5
|
+
let(:geo) { build_geo 20, 0, 640, 480 }
|
6
|
+
let(:entry) { build_entry }
|
7
|
+
let(:entries) { Container.new([entry, build_entry]) }
|
8
|
+
subject(:arranger) { described_class.new entries, geo, width: 300 }
|
9
|
+
|
10
|
+
describe '#arrange' do
|
11
|
+
it 'decreases first entry width as the optimal width' do
|
12
|
+
arranger.arrange
|
13
|
+
expect(entries[0].width).to eq 300
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'offsets entries with given geo' do
|
17
|
+
arranger.arrange
|
18
|
+
expect(entries[0].x).to eq 20
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'moves second entry aside the first entry' do
|
22
|
+
arranger.arrange
|
23
|
+
expect(entries[1].x).to eq 320
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'increases last entry width to occupy remaining width' do
|
27
|
+
arranger.arrange
|
28
|
+
expect(entries[1].width).to eq 340
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'copies given geo y' do
|
32
|
+
entries[0].y = nil
|
33
|
+
arranger.arrange
|
34
|
+
expect(entries[0].y).to eq 0
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'copies given geo height' do
|
38
|
+
entries[0].height = nil
|
39
|
+
arranger.arrange
|
40
|
+
expect(entries[0].height).to eq 480
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'without entry' do
|
44
|
+
let(:entries) { Container.new([]) }
|
45
|
+
|
46
|
+
it 'does not raise any error' do
|
47
|
+
expect { arranger.arrange }.not_to raise_error
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe '#max_count?' do
|
53
|
+
context 'when a new entry fits in current geo' do
|
54
|
+
let(:entries) { Container.new([entry]) }
|
55
|
+
|
56
|
+
it 'returns false' do
|
57
|
+
expect(arranger.max_count?).to be false
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'when current geo can not contain more entry' do
|
62
|
+
let(:entries) { Container.new([entry, entry.dup]) }
|
63
|
+
|
64
|
+
it 'returns true' do
|
65
|
+
expect(arranger.max_count?).to be true
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Uh
|
2
|
+
class Layout
|
3
|
+
module Arrangers
|
4
|
+
describe Stack do
|
5
|
+
let(:entry) { build_entry }
|
6
|
+
let(:other_entry) { build_entry }
|
7
|
+
let(:entries) { Container.new([entry, other_entry]) }
|
8
|
+
let(:geo) { build_geo 0, 0, 300, 480 }
|
9
|
+
subject(:arranger) { described_class.new entries, geo }
|
10
|
+
|
11
|
+
describe '#arrange' do
|
12
|
+
it 'sets given geo on all entries' do
|
13
|
+
arranger.arrange
|
14
|
+
expect(entries.map(&:geo)).to all eq geo
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#each_visible' do
|
19
|
+
it 'yields current entry' do
|
20
|
+
expect { |b| arranger.each_visible &b }
|
21
|
+
.to yield_successive_args entry
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'with no current entry' do
|
25
|
+
let(:entries) { Container.new([]) }
|
26
|
+
|
27
|
+
it 'does not yield' do
|
28
|
+
expect { |b| arranger.each_visible &b }.not_to yield_control
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#each_hidden' do
|
34
|
+
it 'yields all entries except current one' do
|
35
|
+
expect { |b| arranger.each_hidden &b }
|
36
|
+
.to yield_successive_args other_entry
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Uh
|
2
|
+
class Layout
|
3
|
+
module Arrangers
|
4
|
+
describe VertTile do
|
5
|
+
let(:entry) { build_entry }
|
6
|
+
let(:other_entry) { build_entry }
|
7
|
+
let(:entries) { Container.new([entry, other_entry]) }
|
8
|
+
let(:geo) { build_geo 0, 0, 300, 480 }
|
9
|
+
subject(:arranger) { described_class.new entries, geo }
|
10
|
+
|
11
|
+
describe '#arrange' do
|
12
|
+
it 'sets x offset from given geo on all entries' do
|
13
|
+
arranger.arrange
|
14
|
+
expect(entries.map(&:x)).to all eq 0
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'sets width from given geo on all entries' do
|
18
|
+
arranger.arrange
|
19
|
+
expect(entries.map(&:width)).to all eq 300
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'splits entries height equally' do
|
23
|
+
arranger.arrange
|
24
|
+
expect(entries.map(&:height)).to all eq 239
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'adds a margin between entries' do
|
28
|
+
arranger.arrange
|
29
|
+
expect(entries[1].y - entries[0].height - entries[0].y).to eq 1
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#each_visible' do
|
34
|
+
it 'yields all entries' do
|
35
|
+
expect { |b| arranger.each_visible &b }
|
36
|
+
.to yield_successive_args entry, other_entry
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe '#each_hidden' do
|
41
|
+
it 'yields no entry' do
|
42
|
+
expect { |b| arranger.each_hidden &b }.not_to yield_control
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module Uh
|
2
|
+
class Layout
|
3
|
+
describe ClientColumnMover do
|
4
|
+
let(:client) { build_client }
|
5
|
+
let(:column) { Column.new(build_geo) }
|
6
|
+
let(:columns) { Container.new([column]) }
|
7
|
+
let(:columns_max_count) { false }
|
8
|
+
subject(:mover) { described_class.new columns, columns_max_count }
|
9
|
+
|
10
|
+
describe '#move_current' do
|
11
|
+
shared_examples 'moves current client' do |expected_column_index|
|
12
|
+
it 'removes current client from origin column' do
|
13
|
+
mover.move_current :succ
|
14
|
+
expect(column).not_to include client
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'adds current client in the destination column' do
|
18
|
+
mover.move_current :succ
|
19
|
+
expect(columns[expected_column_index]).to include client
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'updates destination column as the current one' do
|
23
|
+
mover.move_current :succ
|
24
|
+
expect(columns.current).to be columns[expected_column_index]
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'preserves current client as the current one' do
|
28
|
+
expect { mover.move_current :succ }
|
29
|
+
.not_to change { columns.current.current_client }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'given one column with one client' do
|
34
|
+
before { column << client }
|
35
|
+
|
36
|
+
include_examples 'moves current client', 1
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'given one column with many clients' do
|
40
|
+
before { column << client << client.dup }
|
41
|
+
|
42
|
+
include_examples 'moves current client', 1
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'given two columns' do
|
46
|
+
let(:columns) { Container.new([column, Column.new(build_geo)]) }
|
47
|
+
|
48
|
+
before { columns[1] << client.dup }
|
49
|
+
|
50
|
+
context 'when origin column has many clients' do
|
51
|
+
before { column << client << client.dup }
|
52
|
+
|
53
|
+
include_examples 'moves current client', 1
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'when origin column has one client' do
|
57
|
+
before { column << client }
|
58
|
+
|
59
|
+
include_examples 'moves current client', 1
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe '#get_or_create_column' do
|
65
|
+
let(:columns) { Container.new([column, Column.new(build_geo)]) }
|
66
|
+
|
67
|
+
it 'returns the consecutive column in given direction' do
|
68
|
+
expect(mover.get_or_create_column :succ).to be columns[1]
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'when current column is last in given direction' do
|
72
|
+
before { columns.current = columns[1] }
|
73
|
+
|
74
|
+
context 'when max columns count is not reached' do
|
75
|
+
it 'appends a new column' do
|
76
|
+
expect(mover.get_or_create_column :succ).to be columns[2]
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'prepends a new column' do
|
80
|
+
columns.current = columns[0]
|
81
|
+
expect(mover.get_or_create_column :pred).to be columns[0]
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context 'when max columns count is reached' do
|
86
|
+
let(:columns_max_count) { true }
|
87
|
+
|
88
|
+
it 'returns the consecutive column in given direction' do
|
89
|
+
expect(mover.get_or_create_column :succ).to be columns[0]
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -5,7 +5,7 @@ module Uh
|
|
5
5
|
let(:other_geo) { build_geo 640, 0, 320, 240 }
|
6
6
|
let(:client) { build_client }
|
7
7
|
let(:other_client) { build_client }
|
8
|
-
subject(:column) { described_class.new
|
8
|
+
subject(:column) { described_class.new geo }
|
9
9
|
|
10
10
|
it 'has a copy to given geo' do
|
11
11
|
expect(column.geo).to eq(geo).and not_be geo
|
@@ -15,6 +15,10 @@ module Uh
|
|
15
15
|
expect(column).to be_empty
|
16
16
|
end
|
17
17
|
|
18
|
+
it 'has :stack as default mode' do
|
19
|
+
expect(column.mode).to be :stack
|
20
|
+
end
|
21
|
+
|
18
22
|
describe '#<<' do
|
19
23
|
before { column << client }
|
20
24
|
|
@@ -31,13 +35,43 @@ module Uh
|
|
31
35
|
end
|
32
36
|
end
|
33
37
|
|
38
|
+
describe '#mode_toggle' do
|
39
|
+
it 'toggles mode from stack to tile' do
|
40
|
+
expect { column.mode_toggle }
|
41
|
+
.to change { column.mode }.from(:stack).to(:tile)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'toggles mode from tile to stack' do
|
45
|
+
column.mode_toggle
|
46
|
+
expect { column.mode_toggle }
|
47
|
+
.to change { column.mode }.from(:tile).to(:stack)
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
describe '#arranger' do
|
53
|
+
context 'when column mode is stack' do
|
54
|
+
it 'returns a stack arranger' do
|
55
|
+
expect(column.arranger).to be_an Arrangers::Stack
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'when column mode is tile' do
|
60
|
+
it 'returns a vertical tile arranger' do
|
61
|
+
column.mode_toggle
|
62
|
+
expect(column.arranger).to be_an Arrangers::VertTile
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
34
67
|
describe '#arrange_clients' do
|
35
68
|
before { column << client << other_client }
|
36
69
|
|
37
|
-
it '
|
38
|
-
|
70
|
+
it 'arranges clients' do
|
71
|
+
arranger = instance_spy Arrangers::Stack
|
72
|
+
allow(column).to receive(:arranger) { arranger }
|
73
|
+
expect(arranger).to receive :arrange
|
39
74
|
column.arrange_clients
|
40
|
-
expect(column.clients.map(&:geo)).to all eq column.geo
|
41
75
|
end
|
42
76
|
|
43
77
|
it 'moveresizes clients' do
|
@@ -47,18 +81,24 @@ module Uh
|
|
47
81
|
end
|
48
82
|
|
49
83
|
describe '#show_hide_clients' do
|
50
|
-
|
84
|
+
let(:arranger) { double 'arranger', each_visible: nil, each_hidden: nil }
|
51
85
|
|
52
|
-
it 'shows
|
86
|
+
it 'shows visible clients when they are hidden' do
|
87
|
+
allow(arranger).to receive(:each_visible)
|
88
|
+
.and_yield(client.hide)
|
89
|
+
.and_yield(other_client.show)
|
90
|
+
expect(client).to receive :show
|
53
91
|
expect(other_client).not_to receive :show
|
54
|
-
|
55
|
-
column.show_hide_clients
|
92
|
+
column.show_hide_clients arranger: arranger
|
56
93
|
end
|
57
94
|
|
58
|
-
it 'hides
|
59
|
-
|
60
|
-
|
61
|
-
|
95
|
+
it 'hides hidden clients except those already hidden' do
|
96
|
+
allow(arranger).to receive(:each_hidden)
|
97
|
+
.and_yield(client.show)
|
98
|
+
.and_yield(other_client.hide)
|
99
|
+
expect(client).to receive :hide
|
100
|
+
expect(other_client).not_to receive :hide
|
101
|
+
column.show_hide_clients arranger: arranger
|
62
102
|
end
|
63
103
|
end
|
64
104
|
end
|
@@ -42,9 +42,9 @@ module Uh
|
|
42
42
|
end
|
43
43
|
|
44
44
|
context 'when given argument is not an entry' do
|
45
|
-
it '
|
46
|
-
expect { container.current = :
|
47
|
-
.
|
45
|
+
it 'raises ArgumentError' do
|
46
|
+
expect { container.current = :unknown_entry }
|
47
|
+
.to raise_error Layout::ArgumentError
|
48
48
|
end
|
49
49
|
end
|
50
50
|
end
|
@@ -91,10 +91,10 @@ module Uh
|
|
91
91
|
end
|
92
92
|
|
93
93
|
context 'when given entry is the only one' do
|
94
|
-
let(:entries) { [:
|
94
|
+
let(:entries) { [:bar] }
|
95
95
|
|
96
96
|
it 'has no more current entry' do
|
97
|
-
container.remove :
|
97
|
+
container.remove :bar
|
98
98
|
expect(container.current).to be nil
|
99
99
|
end
|
100
100
|
end
|
@@ -4,7 +4,7 @@ module Uh
|
|
4
4
|
let(:geo) { build_geo }
|
5
5
|
let(:other_geo) { build_geo 640, 0, 320, 240 }
|
6
6
|
let(:client) { build_client }
|
7
|
-
subject(:screen) { described_class.new
|
7
|
+
subject(:screen) { described_class.new 0, geo }
|
8
8
|
|
9
9
|
it 'has one default tag with id 1 assigned' do
|
10
10
|
expect(screen.tags).to include an_object_having_attributes id: '1'
|
data/spec/uh/layout/tag_spec.rb
CHANGED
@@ -6,11 +6,12 @@ module Uh
|
|
6
6
|
let(:client) { build_client }
|
7
7
|
let(:other_client) { build_client }
|
8
8
|
let(:column) { Column.new(geo) }
|
9
|
-
subject(:tag) { described_class.new
|
9
|
+
subject(:tag) { described_class.new '1', geo }
|
10
10
|
|
11
11
|
describe '.new' do
|
12
12
|
it 'raises error unless id converts to string' do
|
13
|
-
expect { described_class.new
|
13
|
+
expect { described_class.new 1, geo }
|
14
|
+
.to raise_error(Layout::ArgumentError)
|
14
15
|
end
|
15
16
|
end
|
16
17
|
|
@@ -40,7 +41,7 @@ module Uh
|
|
40
41
|
end
|
41
42
|
|
42
43
|
it 'returns the new column' do
|
43
|
-
expect(tag.current_column_or_create).to
|
44
|
+
expect(tag.current_column_or_create).to be tag.columns.fetch 0
|
44
45
|
end
|
45
46
|
end
|
46
47
|
|
@@ -57,6 +58,34 @@ module Uh
|
|
57
58
|
end
|
58
59
|
end
|
59
60
|
end
|
61
|
+
|
62
|
+
describe '#arranger' do
|
63
|
+
it 'returns a fixed width arranger' do
|
64
|
+
expect(tag.arranger).to be_an Arrangers::FixedWidth
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe '#arrange_columns' do
|
69
|
+
before { tag.columns << column }
|
70
|
+
|
71
|
+
it 'purges empty columns' do
|
72
|
+
tag.arrange_columns
|
73
|
+
expect(tag.columns).to be_empty
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'arranges columns' do
|
77
|
+
arranger = instance_spy Arrangers::FixedWidth
|
78
|
+
allow(tag).to receive(:arranger) { arranger }
|
79
|
+
expect(arranger).to receive :arrange
|
80
|
+
tag.arrange_columns
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'arranges columns clients' do
|
84
|
+
column << client
|
85
|
+
expect(column).to receive :arrange_clients
|
86
|
+
tag.arrange_columns
|
87
|
+
end
|
88
|
+
end
|
60
89
|
end
|
61
90
|
end
|
62
91
|
end
|
data/spec/uh/layout_spec.rb
CHANGED
@@ -23,17 +23,6 @@ module Uh
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
-
describe '#arranger_for_current_tag' do
|
27
|
-
it 'returns an arranger for current tag columns and geo' do
|
28
|
-
expect(layout.arranger_for_current_tag)
|
29
|
-
.to respond_to(:update_geos)
|
30
|
-
.and have_attributes(
|
31
|
-
columns: layout.current_tag.columns,
|
32
|
-
geo: layout.current_tag.geo
|
33
|
-
)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
26
|
describe '#update_widgets' do
|
38
27
|
it 'updates widgets' do
|
39
28
|
expect(layout.widgets).to all receive :update
|
@@ -110,13 +99,8 @@ module Uh
|
|
110
99
|
expect(layout).not_to include client
|
111
100
|
end
|
112
101
|
|
113
|
-
it '
|
114
|
-
|
115
|
-
layout.remove client
|
116
|
-
end
|
117
|
-
|
118
|
-
it 'arranges clients in removed client tag columns' do
|
119
|
-
expect(layout.current_tag.columns).to all receive :arrange_clients
|
102
|
+
it 'arranges columns in removed client tag' do
|
103
|
+
expect(layout.current_tag).to receive :arrange_columns
|
120
104
|
layout.remove client
|
121
105
|
end
|
122
106
|
|
@@ -229,8 +213,8 @@ module Uh
|
|
229
213
|
expect(origin_tag).not_to include client
|
230
214
|
end
|
231
215
|
|
232
|
-
it '
|
233
|
-
expect(layout
|
216
|
+
it 'removes current client from layout' do
|
217
|
+
expect(layout).to receive(:remove).with client
|
234
218
|
layout.handle_tag_set '2'
|
235
219
|
end
|
236
220
|
|
@@ -245,10 +229,9 @@ module Uh
|
|
245
229
|
expect(dest_tag).to include client
|
246
230
|
end
|
247
231
|
|
248
|
-
it '
|
249
|
-
layout.current_screen.tags << tag = Layout::Tag.new('2', geo)
|
250
|
-
expect(tag.current_column_or_create).to receive :arrange_clients
|
232
|
+
it 'preserves current tag' do
|
251
233
|
layout.handle_tag_set '2'
|
234
|
+
expect(layout.current_tag.id).to eq '1'
|
252
235
|
end
|
253
236
|
|
254
237
|
it 'updates widgets' do
|
@@ -290,6 +273,33 @@ module Uh
|
|
290
273
|
end
|
291
274
|
end
|
292
275
|
|
276
|
+
describe '#handle_column_mode_toggle' do
|
277
|
+
context 'without column' do
|
278
|
+
it 'does not raise any error' do
|
279
|
+
expect { layout.handle_column_mode_toggle }.not_to raise_error
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
context 'with a column' do
|
284
|
+
before { layout << client }
|
285
|
+
|
286
|
+
it 'toggles current column mode' do
|
287
|
+
expect(layout.current_column).to receive :mode_toggle
|
288
|
+
layout.handle_column_mode_toggle
|
289
|
+
end
|
290
|
+
|
291
|
+
it 'arranges current column clients' do
|
292
|
+
expect(layout.current_column).to receive :arrange_clients
|
293
|
+
layout.handle_column_mode_toggle
|
294
|
+
end
|
295
|
+
|
296
|
+
it 'shows and hides clients in current column' do
|
297
|
+
expect(layout.current_column).to receive :show_hide_clients
|
298
|
+
layout.handle_column_mode_toggle
|
299
|
+
end
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
293
303
|
describe '#handle_client_sel' do
|
294
304
|
context 'without client' do
|
295
305
|
it 'does not raise any error' do
|
@@ -358,22 +368,17 @@ module Uh
|
|
358
368
|
end
|
359
369
|
|
360
370
|
context 'with one column and two clients' do
|
361
|
-
let(:
|
371
|
+
let(:mover) { instance_spy Layout::ClientColumnMover }
|
362
372
|
|
363
373
|
before { layout << other_client << client }
|
364
374
|
|
365
|
-
it 'moves current client with column
|
366
|
-
expect(
|
367
|
-
layout.handle_client_column_set :succ,
|
368
|
-
end
|
369
|
-
|
370
|
-
it 'updates columns geos with column arranger' do
|
371
|
-
expect(arranger).to receive :update_geos
|
372
|
-
layout.handle_client_column_set :succ, arranger: arranger
|
375
|
+
it 'moves current client with given client column mover' do
|
376
|
+
expect(mover).to receive(:move_current).with(:succ)
|
377
|
+
layout.handle_client_column_set :succ, mover: mover
|
373
378
|
end
|
374
379
|
|
375
|
-
it 'arranges
|
376
|
-
expect(layout.current_tag
|
380
|
+
it 'arranges current tag columns' do
|
381
|
+
expect(layout.current_tag).to receive :arrange_columns
|
377
382
|
layout.handle_client_column_set :succ
|
378
383
|
end
|
379
384
|
|
data/uh-layout.gemspec
CHANGED
@@ -15,8 +15,7 @@ Gem::Specification.new do |s|
|
|
15
15
|
s.executables = s.files.grep(/\Abin\//) { |f| File.basename(f) }
|
16
16
|
|
17
17
|
|
18
|
-
s.
|
19
|
-
|
18
|
+
s.add_development_dependency 'uh'
|
20
19
|
s.add_development_dependency 'rake', '~> 10.4'
|
21
20
|
s.add_development_dependency 'rspec', '~> 3.2'
|
22
21
|
end
|
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: uh-layout
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thibault Jouan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-03-
|
11
|
+
date: 2015-03-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: uh
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0
|
20
|
-
type: :
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0
|
26
|
+
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -60,23 +60,28 @@ extra_rdoc_files: []
|
|
60
60
|
files:
|
61
61
|
- ".gitignore"
|
62
62
|
- ".rspec"
|
63
|
+
- ".travis.yml"
|
63
64
|
- Gemfile
|
64
|
-
- Gemfile-custom.rb
|
65
65
|
- Guardfile
|
66
66
|
- Rakefile
|
67
67
|
- lib/uh/layout.rb
|
68
|
+
- lib/uh/layout/arrangers/fixed_width.rb
|
69
|
+
- lib/uh/layout/arrangers/stack.rb
|
70
|
+
- lib/uh/layout/arrangers/vert_tile.rb
|
68
71
|
- lib/uh/layout/bar.rb
|
72
|
+
- lib/uh/layout/client_column_mover.rb
|
69
73
|
- lib/uh/layout/column.rb
|
70
|
-
- lib/uh/layout/column/arranger.rb
|
71
74
|
- lib/uh/layout/container.rb
|
72
75
|
- lib/uh/layout/dumper.rb
|
73
|
-
- lib/uh/layout/geo_accessors.rb
|
74
76
|
- lib/uh/layout/screen.rb
|
75
77
|
- lib/uh/layout/tag.rb
|
76
78
|
- lib/uh/layout/version.rb
|
77
79
|
- spec/spec_helper.rb
|
78
80
|
- spec/support/factories.rb
|
79
|
-
- spec/uh/layout/
|
81
|
+
- spec/uh/layout/arrangers/fixed_width_spec.rb
|
82
|
+
- spec/uh/layout/arrangers/stack_spec.rb
|
83
|
+
- spec/uh/layout/arrangers/vert_tile_spec.rb
|
84
|
+
- spec/uh/layout/client_column_mover_spec.rb
|
80
85
|
- spec/uh/layout/column_spec.rb
|
81
86
|
- spec/uh/layout/container_spec.rb
|
82
87
|
- spec/uh/layout/screen_spec.rb
|
@@ -109,7 +114,10 @@ summary: Simple layout for uh
|
|
109
114
|
test_files:
|
110
115
|
- spec/spec_helper.rb
|
111
116
|
- spec/support/factories.rb
|
112
|
-
- spec/uh/layout/
|
117
|
+
- spec/uh/layout/arrangers/fixed_width_spec.rb
|
118
|
+
- spec/uh/layout/arrangers/stack_spec.rb
|
119
|
+
- spec/uh/layout/arrangers/vert_tile_spec.rb
|
120
|
+
- spec/uh/layout/client_column_mover_spec.rb
|
113
121
|
- spec/uh/layout/column_spec.rb
|
114
122
|
- spec/uh/layout/container_spec.rb
|
115
123
|
- spec/uh/layout/screen_spec.rb
|
data/Gemfile-custom.rb
DELETED
@@ -1,66 +0,0 @@
|
|
1
|
-
module Uh
|
2
|
-
class Layout
|
3
|
-
class Column
|
4
|
-
class Arranger
|
5
|
-
OPTIMAL_WIDTH = 484
|
6
|
-
|
7
|
-
attr_reader :columns, :geo
|
8
|
-
|
9
|
-
def initialize(columns, geo, column_width: OPTIMAL_WIDTH)
|
10
|
-
@columns = columns
|
11
|
-
@geo = geo
|
12
|
-
@column_width = column_width
|
13
|
-
end
|
14
|
-
|
15
|
-
def redraw
|
16
|
-
purge
|
17
|
-
update_geos
|
18
|
-
yield if block_given?
|
19
|
-
end
|
20
|
-
|
21
|
-
def purge
|
22
|
-
@columns.remove_if &:empty?
|
23
|
-
end
|
24
|
-
|
25
|
-
def move_current_client(direction)
|
26
|
-
return self unless @columns.current.current_client
|
27
|
-
@columns.current.remove client = @columns.current.current_client
|
28
|
-
dest_column = get_or_create_column direction
|
29
|
-
dest_column << client
|
30
|
-
dest_column.current_client = client
|
31
|
-
purge
|
32
|
-
@columns.current = dest_column
|
33
|
-
self
|
34
|
-
end
|
35
|
-
|
36
|
-
def get_or_create_column(direction)
|
37
|
-
if candidate = @columns.get(direction)
|
38
|
-
candidate
|
39
|
-
elsif max_columns_count?
|
40
|
-
@columns.get direction, cycle: true
|
41
|
-
else
|
42
|
-
Column.new(@geo).tap do |o|
|
43
|
-
case direction
|
44
|
-
when :pred then @columns.unshift o
|
45
|
-
when :succ then @columns << o
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def max_columns_count?
|
52
|
-
(@geo.width / (@columns.size + 1)) < @column_width
|
53
|
-
end
|
54
|
-
|
55
|
-
def update_geos
|
56
|
-
return if @columns.empty?
|
57
|
-
@columns.each_with_index do |column, i|
|
58
|
-
column.x = @column_width * i + @geo.x
|
59
|
-
column.width = @column_width
|
60
|
-
end
|
61
|
-
@columns.last.width = @geo.width - (@columns.last.x - @geo.x)
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
@@ -1,181 +0,0 @@
|
|
1
|
-
module Uh
|
2
|
-
class Layout
|
3
|
-
class Column
|
4
|
-
describe Arranger do
|
5
|
-
let(:geo) { build_geo }
|
6
|
-
let(:client) { build_client }
|
7
|
-
let(:column_width) { 300 }
|
8
|
-
let(:column) { Column.new(geo) }
|
9
|
-
let(:columns) { Container.new([column]) }
|
10
|
-
subject(:arranger) { described_class.new columns, geo,
|
11
|
-
column_width: column_width }
|
12
|
-
|
13
|
-
describe '#redraw' do
|
14
|
-
it 'purges columns' do
|
15
|
-
expect(arranger).to receive :purge
|
16
|
-
arranger.redraw
|
17
|
-
end
|
18
|
-
|
19
|
-
it 'updates columns geo' do
|
20
|
-
expect(arranger).to receive :update_geos
|
21
|
-
arranger.redraw
|
22
|
-
end
|
23
|
-
|
24
|
-
it 'yields given block' do
|
25
|
-
expect { |b| arranger.redraw &b }.to yield_control
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
describe '#purge' do
|
30
|
-
it 'removes empty columns' do
|
31
|
-
arranger.purge
|
32
|
-
expect(columns).to be_empty
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
describe '#move_current_client' do
|
37
|
-
shared_examples 'moves current client' do |expected_column_index|
|
38
|
-
it 'removes current client from origin column' do
|
39
|
-
arranger.move_current_client :succ
|
40
|
-
expect(column).not_to include client
|
41
|
-
end
|
42
|
-
|
43
|
-
it 'adds current client in the destination column' do
|
44
|
-
arranger.move_current_client :succ
|
45
|
-
expect(columns[expected_column_index]).to include client
|
46
|
-
end
|
47
|
-
|
48
|
-
it 'updates destination column as the current one' do
|
49
|
-
arranger.move_current_client :succ
|
50
|
-
expect(columns.current).to be columns[expected_column_index]
|
51
|
-
end
|
52
|
-
|
53
|
-
it 'preserves current client as the current one' do
|
54
|
-
expect { arranger.move_current_client :succ }
|
55
|
-
.not_to change { columns.current.current_client }
|
56
|
-
end
|
57
|
-
|
58
|
-
it 'does not leave empty columns' do
|
59
|
-
expect(columns.none? &:empty?).to be true
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
it 'returns self' do
|
64
|
-
expect(arranger.move_current_client :succ).to be arranger
|
65
|
-
end
|
66
|
-
|
67
|
-
context 'given one column with one client' do
|
68
|
-
before { column << client }
|
69
|
-
|
70
|
-
include_examples 'moves current client', 0
|
71
|
-
end
|
72
|
-
|
73
|
-
context 'given one column with many clients' do
|
74
|
-
before { column << client << client.dup }
|
75
|
-
|
76
|
-
include_examples 'moves current client', 1
|
77
|
-
end
|
78
|
-
|
79
|
-
context 'given two columns' do
|
80
|
-
let(:columns) { Container.new([column, Column.new(geo)]) }
|
81
|
-
|
82
|
-
before { columns[1] << client.dup }
|
83
|
-
|
84
|
-
context 'when origin column has many clients' do
|
85
|
-
before { column << client << client.dup }
|
86
|
-
|
87
|
-
include_examples 'moves current client', 1
|
88
|
-
end
|
89
|
-
|
90
|
-
context 'when origin column has one client' do
|
91
|
-
before { column << client }
|
92
|
-
|
93
|
-
include_examples 'moves current client', 0
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
describe '#get_or_create_column' do
|
99
|
-
let(:columns) { Container.new([column, Column.new(geo)]) }
|
100
|
-
|
101
|
-
it 'returns the consecutive column in given direction' do
|
102
|
-
expect(arranger.get_or_create_column :succ).to be columns[1]
|
103
|
-
end
|
104
|
-
|
105
|
-
context 'when current column is last in given direction' do
|
106
|
-
before { columns.current = columns[1] }
|
107
|
-
|
108
|
-
context 'when max columns count is not reached' do
|
109
|
-
before { geo.width = 4096 }
|
110
|
-
|
111
|
-
it 'appends a new column' do
|
112
|
-
expect(arranger.get_or_create_column :succ).to be columns[2]
|
113
|
-
end
|
114
|
-
|
115
|
-
it 'prepends a new column' do
|
116
|
-
columns.current = columns[0]
|
117
|
-
expect(arranger.get_or_create_column :pred).to be columns[0]
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
context 'when max columns count is reached' do
|
122
|
-
it 'returns the consecutive column in given direction' do
|
123
|
-
expect(arranger.get_or_create_column :succ).to be columns[0]
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
describe '#max_columns_count?' do
|
130
|
-
context 'when a new column fits in current geo' do
|
131
|
-
it 'returns false' do
|
132
|
-
expect(arranger.max_columns_count?).to be false
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
context 'when current geo can not contain more column' do
|
137
|
-
let(:columns) { Container.new([column, Column.new(geo)]) }
|
138
|
-
|
139
|
-
it 'returns true' do
|
140
|
-
expect(arranger.max_columns_count?).to be true
|
141
|
-
end
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
describe '#update_geos' do
|
146
|
-
let(:columns) { Container.new([column, Column.new(geo)]) }
|
147
|
-
|
148
|
-
before { geo.x = 20 }
|
149
|
-
|
150
|
-
it 'decreases first column width as the optimal column width' do
|
151
|
-
arranger.update_geos
|
152
|
-
expect(columns[0].width).to eq 300
|
153
|
-
end
|
154
|
-
|
155
|
-
it 'offsets each column with given geo' do
|
156
|
-
arranger.update_geos
|
157
|
-
expect(columns[0].x).to eq 20
|
158
|
-
end
|
159
|
-
|
160
|
-
it 'moves second column aside the first column' do
|
161
|
-
arranger.update_geos
|
162
|
-
expect(columns[1].x).to eq 320
|
163
|
-
end
|
164
|
-
|
165
|
-
it 'increases last column width to occupy remaining width' do
|
166
|
-
arranger.update_geos
|
167
|
-
expect(columns[1].width).to eq 340
|
168
|
-
end
|
169
|
-
|
170
|
-
context 'without columns' do
|
171
|
-
let(:columns) { Container.new([]) }
|
172
|
-
|
173
|
-
it 'does not raise any error' do
|
174
|
-
expect { arranger.update_geos }.not_to raise_error
|
175
|
-
end
|
176
|
-
end
|
177
|
-
end
|
178
|
-
end
|
179
|
-
end
|
180
|
-
end
|
181
|
-
end
|