File: layout_methods.rb

package info (click to toggle)
ruby-compass 0.12.2~dfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 8,308 kB
  • sloc: ruby: 10,474; makefile: 42; xml: 14
file content (159 lines) | stat: -rw-r--r-- 5,006 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
module Compass
  module SassExtensions
    module Sprites
      module LayoutMethods
        HORIZONTAL = 'horizontal'
        DIAGONAL = 'diagonal'
        SMART = 'smart'
        VERTICAL = 'vertical'
        
        def smart?
          layout == SMART
        end
        
        def horizontal?
          layout == HORIZONTAL
        end
        
        def diagonal?
          layout == DIAGONAL
        end

        def vertical?
          layout == VERTICAL
        end
        
        def layout
          @layout ||= @kwargs.get_var('layout').value
        end
        
        # Calculates the overal image dimensions
        # collects image sizes and input parameters for each sprite
        def compute_image_positions!
          case layout
          when SMART
            calculate_smart_positions
          when DIAGONAL
            calculate_diagonal_dimensions
            calculate_diagonal_positions
          when HORIZONTAL
            @height = height_for_horizontal_layout
            calculate_horizontal_positions
            @width = width_for_horizontal_layout
          else
            @images.sort! do |a,b| 
              if (b.size <=> a.size) === 0
                a.name <=> b.name
              else
                b.size <=> a.size
              end
            end

            @width = width_for_vertical_layout
            calulate_vertical_postions
            @height = height_for_vertical_layout
            if @images.any?(&:repeat_x?)
              calculate_repeat_extra_width!
              tile_images_that_repeat
             end
          end
        end

        def tile_images_that_repeat
          @images.map {|img| img if img.repeat_x?}.compact.each do |image|
            x = image.left - (image.left / image.width).ceil * image.width
              while x < @width do
                begin
                  img = image.dup
                  img.top = image.top
                  img.left = x.to_i
                  @images << img
                  x += image.width 
                end
              end
            end
        end

        def calculate_repeat_extra_width!
          require 'rational' #for ruby 1.8.7
          m = @images.inject(1) {|m,img| img.repeat_x? ? m.lcm(img.width) : m}
          remainder = @width % m
          @width += (m - remainder) unless remainder.zero?
        end
        
        def calculate_smart_positions
          fitter = ::Compass::SassExtensions::Sprites::RowFitter.new(@images)
          current_y = 0
          fitter.fit!.each do |row|
            current_x = 0
            row.images.each_with_index do |image, index|
              image.left = current_x
              image.top = current_y
              current_x += image.width
            end
            current_y += row.height
          end
          @width = fitter.width
          @height = fitter.height
        end
        
        
        def calculate_diagonal_dimensions
          @width = @images.inject(0) {|sum, img| sum + img.width}
          @height = @images.inject(0) {|sum, img| sum + img.height}
        end
        
        def calculate_diagonal_positions
          previous = nil
          @images.each_with_index do |image, index|
            if previous.nil?
              previous = image
              image.top = @height - image.height
              image.left = 0
              next
            end
            image.top = previous.top - image.height
            image.left = previous.left + previous.width
            previous = image
          end
        end
        
        def calculate_horizontal_positions
          @images.each_with_index do |image, index|
            image.top = image.position.unit_str == '%' ? (@height - image.height) * (image.position.value / 100.0) : image.position.value
            next if index == 0
            last_image = @images[index-1]
            image.left = last_image.left + last_image.width + [image.spacing, last_image.spacing].max
          end
        end
        
        def calulate_vertical_postions
          @images.each_with_index do |image, index|
            image.left = (image.position.unit_str == "%" ? (@width - image.width) * (image.position.value / 100.0) : image.position.value).to_i
            next if index == 0
            last_image = @images[index-1]
            image.top = last_image.top + last_image.height + [image.spacing,  last_image.spacing].max
          end
        end
        
        def height_for_vertical_layout
          last = @images.last
          last.top + last.height
        end
        
        def height_for_horizontal_layout
          @height = @images.map {|image| image.height + image.offset}.max
        end
        
        def width_for_horizontal_layout
          @images.inject(0) { |sum, image| sum += (image.width + image.spacing) }
        end
        
        def width_for_vertical_layout
          @images.map { |image| image.width + image.offset }.max
        end
      end
    end
  end
end