extjs-theme 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -22,9 +22,9 @@ to you Gemfile and execute
22
22
 
23
23
  In the root of your Rails app, first execute the following in your console:
24
24
 
25
- $ bundle exec xtheme init
25
+ $ bundle exec xtheme init <path/to/ext> <path/to/stylesheets/sass-dir>
26
26
 
27
- This creates a YAML config file named config/xtheme.yml in the application root.
27
+ This creates a YAML config file named config/xtheme.yml in the application root. </path/to/ext> defaults to <code>public/javascripts/ext-3.2</code> and </path/to/stylesheets/sass-dir> defaults to <code>public/stylesheets/themes</code>.
28
28
 
29
29
  ---
30
30
  theme_dir: app/stylesheets/themes
@@ -44,43 +44,43 @@ To generate a new Sass theme:
44
44
 
45
45
  $ bundle exec xtheme create my-theme
46
46
 
47
- In Rails, this will have created a new directory <code>public/stylesheets/sass/my-theme</code>
47
+ In Rails, this will have created a new directory <code>public/stylesheets/themes/my-theme</code>
48
48
 
49
49
  The generator creates a main include file called <code>my-theme/all.sass</code> which contains <code>@include</code> directives for each individual Ext stylesheet. You *no longer need* to include the ext-all.css file from the Ext library -- <code>my-theme/all.sass</code> contains all it needs. In a Rails view, you would include this file in the standard Haml/Sass[http://sass-lang.com/] manner.
50
50
 
51
- =stylesheet_link_tag "my-theme/init"
51
+ =stylesheet_link_tag "my-theme/all"
52
52
 
53
53
  or in an <code>erb</code> template:
54
54
 
55
- <%= stylesheet_link_tag "my-theme/init"
55
+ <%= stylesheet_link_tag "my-theme/all"
56
56
 
57
57
  The generator also creates a copy of all the Ext theme images in <code>my-theme/images</code>
58
58
 
59
59
  Another important sass file created is <code>my-theme/defines.sass</code>. This file contains Sass variable declarations added to each Ext sass file.
60
60
 
61
- !img_path = ../themes/my-theme/images
62
- !font = tahoma,arial,verdana,sans-serif
63
- !hue = -90.0
61
+ $img_path: '../themes/my-theme/images'
62
+ $font: tahoma,arial,verdana,sans-serif
63
+ $hue: -90.0
64
64
 
65
- Form more on Haml and Sass, consult the HAML documentation[http://haml-lang.com/] to learn about including Sass[http://sass-lang.com/] stylesheets.
65
+ For more on Haml and Sass, consult the HAML documentation[http://haml-lang.com/] to learn about including Sass[http://sass-lang.com/] stylesheets.
66
66
 
67
67
  == Effects
68
68
 
69
69
  The Gem includes commands for theme colorization, including image-processing through RMagick.
70
70
 
71
- Currently, the only effect available is <code>effects:modulate</code>, for modifying the _hue_, _saturation_ and _lightness_ of a theme according to RMagick[http://www.imagemagick.org/RMagick/doc/image2.html#modulate]:
71
+ Currently, the only effect available is <code>modulate</code>, for modifying the _hue_, _saturation_ and _lightness_ of a theme according to RMagick[http://www.imagemagick.org/RMagick/doc/image2.html#modulate]:
72
72
 
73
- $ bundle exec xtheme effects:modulate <theme-name> <hue> <saturation> <lightness>
73
+ $ bundle exec xtheme modulate <theme-name> <hue> <saturation> <lightness>
74
74
 
75
- The parameters _hue_, _saturation_ and _lightness_ are defined as {"Float numbers, for example, 0.25 means "25%". All three arguments may be omitted. The default value of each argument is 1.0, that is, 100%"}[http://www.imagemagick.org/RMagick/doc/image2.html#modulate]
75
+ The parameters _hue_, _saturation_ and _lightness_ are defined as {"Float numbers, for example, 0.25 means "25%". The median value of each argument is 1.0, that is, 100%"}[http://www.imagemagick.org/RMagick/doc/image2.html#modulate]
76
76
 
77
77
  Based upon the default blue Ext theme, the following will generate a pink theme:
78
78
 
79
- $ bundle exec xtheme effects:modulate my-theme 0.5 1.0 1.0
79
+ $ bundle exec xtheme modulate my-theme 0.5 1.0 1.0
80
80
 
81
81
  A green theme:
82
82
 
83
- $ bundle exec xtheme effects:modulate my-theme 1.5 1.0 1.0
83
+ $ bundle exec xtheme modulate my-theme 1.5 1.0 1.0
84
84
 
85
85
  *Only hue works currently, saturation and lightness are under development*
86
86
 
data/bin/xtheme CHANGED
@@ -5,10 +5,20 @@ require 'rubygems'
5
5
  $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../lib')
6
6
 
7
7
  require 'extjs-theme'
8
- require 'extjs-theme/command'
8
+ require 'extjs-theme/cli'
9
9
 
10
- args = ARGV.dup
11
- ARGV.clear
12
- command = args.shift.strip rescue 'help'
10
+ begin
11
+ ExtJS::Theme::CLI.start(ARGV, {})
12
+ rescue ExtJS::Theme::Error => e
13
+ puts e.message
14
+ exit e.status_code
15
+ end
13
16
 
14
- ExtJS::Theme::Command.run(command, args)
17
+ # GET RID OF THIS ONCE Thor is in place
18
+ #require 'extjs-theme/command'
19
+
20
+ #args = ARGV.dup
21
+ #ARGV.clear
22
+ #command = args.shift.strip rescue 'help'
23
+
24
+ #ExtJS::Theme::Command.run(command, args)
@@ -2,12 +2,106 @@
2
2
  # XTheme
3
3
  # A module for generating and colorizing ExtJS themes.
4
4
  #
5
+ require 'fileutils'
6
+ require 'yaml'
7
+ require 'thor'
8
+ require 'thor/group'
9
+ require 'sass'
10
+ require 'sass/css'
11
+ require 'RMagick'
12
+
5
13
  module ExtJS
6
14
  module Theme
7
- end
8
- end
9
- $LOAD_PATH.unshift(File.dirname(__FILE__) + '/extjs-theme')
15
+ ROOT = File.dirname(__FILE__)
16
+
17
+ DEFAULT_EXT_DIR = "public/javascripts/ext-3.2"
18
+ DEFAULT_THEME_DIR = "public/stylesheets/themes"
19
+
20
+ ##
21
+ # Define Error classes
22
+ #
23
+ class Error < StandardError
24
+ def self.status_code(code = nil)
25
+ return @code unless code
26
+ @code = code
27
+ end
10
28
 
11
- ['dependencies', 'generator', 'effects'].each do |file|
12
- require file
29
+ def status_code
30
+ self.class.status_code
31
+ end
32
+ end
33
+
34
+ class ArgumentError < Error; status_code(1); end
35
+ class ConfigurationNotFound < Error; status_code(2); end
36
+ class ConfigurationError < Error; status_code(3); end
37
+
38
+ ##
39
+ # Class Methods
40
+ #
41
+ class << self
42
+
43
+ ##
44
+ # Xtheme config accessor
45
+ #
46
+ def [](key)
47
+ (@config ||= configure)[key]
48
+ end
49
+
50
+ ##
51
+ # Convert css file to sass
52
+ # @param {String} file The css filename to convert to sass
53
+ # @return {String}
54
+ #
55
+ def css2sass(file)
56
+ sass = Sass::CSS.new(File.read(file)).render
57
+ sass.gsub!(/background-image: url\(\.\.\/images\/default(.*)\)/, 'background-image: url (#{$img_path+"\1"})')
58
+ sass.gsub!(/(.*):\s?#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/, '\1: adjust_hue(#\2, $hue)')
59
+ "@import '../defines.sass'\n#{sass}"
60
+ end
61
+
62
+ ##
63
+ # Iterate all theme images and yield Magick::ImageList
64
+ #
65
+ def each_image
66
+ path = File.join(self['ext_dir'], "resources", "images", "default")
67
+
68
+ Dir["#{path}/*"].each do |dir|
69
+ Dir[dir+'/*.gif'].each do |filename|
70
+ yield(Magick::ImageList.new(filename))
71
+ end
72
+ Dir[dir+'/*.png'].each do |filename|
73
+ yield(Magick::ImageList.new(filename))
74
+ end
75
+ end
76
+ # Now transform any images left in the base /images/default directory (excluding s.gif)
77
+ Dir["#{path}/*.*"].reject {|f| f.match('s.gif')}.each do |filename|
78
+ yield(Magick::ImageList.new(filename))
79
+ end
80
+ end
81
+
82
+ ##
83
+ # Write transformed RMagick::Image to theme directory
84
+ # @param {RMagick::Image} img
85
+ # @param {String} dest Theme directory
86
+ #
87
+ def write_image(img, dest)
88
+ # Get filename and directory.
89
+ # Need to know if we're writing to /images/<package>/filename.gif OR /images/filename.gif
90
+ m = /\/default\/(.*)\/(.*)\.(.*)$/.match(img.filename) || /\/default\/(.*)\.(.*)$/.match(img.filename)
91
+ outfile = (m.captures.length == 3) ? File.join(dest, "images", m[1], "#{m[2]}.#{m[3]}") : File.join(dest, "images", "#{m[1]}.#{m[2]}")
92
+ img.write(outfile)
93
+ end
94
+
95
+ private
96
+
97
+ def configure
98
+ unless File.exists?("config/xtheme.yml")
99
+ raise ConfigurationNotFound.new('This command must be run from inside a valid application')
100
+ end
101
+ cfg = YAML.load_file("config/xtheme.yml")
102
+ cfg["ext_dir"] = File.expand_path(cfg["ext_dir"])
103
+ cfg
104
+ end
105
+ end
106
+ end
13
107
  end
@@ -0,0 +1,78 @@
1
+ module ExtJS
2
+ module Theme
3
+ class CLI < Thor
4
+ include Thor::Actions
5
+
6
+ ARGV = ::ARGV.dup
7
+
8
+ ##
9
+ # Required by thor
10
+ # Defines the source root-directory when copying files.
11
+ #
12
+ def self.source_root
13
+ ExtJS::Theme["ext_dir"]
14
+ end
15
+
16
+ desc "init <path/to/ext> <path/to/stylesheets/sass-dir>", "Initialize extjs-theme for the current application. Creates config/xtheme.yml"
17
+ def init (ext_dir = ExtJS::Theme::DEFAULT_EXT_DIR, theme_dir = ExtJS::Theme::DEFAULT_THEME_DIR)
18
+ empty_directory("config") unless File.exists?("config")
19
+ inside("config") do
20
+ create_file("xtheme.yml", {
21
+ "ext_dir" => ext_dir,
22
+ "theme_dir" => theme_dir
23
+ }.to_yaml)
24
+ end
25
+ end
26
+
27
+ desc "create <theme-name>", "Creates a new sass-theme"
28
+ def create(name)
29
+ self.class.source_root
30
+
31
+ ext_css_path = File.join(ExtJS::Theme["ext_dir"], "resources", "css")
32
+ theme_path = File.join(ExtJS::Theme["theme_dir"], name)
33
+
34
+ # Create theme directory in /stylesheets/sass
35
+ FileUtils.mkdir_p ["#{theme_path}/visual", "#{theme_path}/structure"]
36
+
37
+ inside theme_path do
38
+ # load the defines.sass template file
39
+ data = File.read(File.join(File.dirname(__FILE__), "template", "defines.sass"))
40
+ img_path = theme_path.split("/")
41
+ img_path.shift # get rid of /public bit
42
+
43
+ # replace img_path sass_var with the location of theme's image-path
44
+ data.gsub!(/\{\{img_path\}\}/, File.join("/", img_path.join('/'), "images"))
45
+
46
+ # write contents to defines.sass
47
+ sass_files = [];
48
+ create_file("defines.sass", data, :force => true)
49
+ ["structure", "visual"].each do |subdir|
50
+ inside subdir do
51
+ Dir["#{self.class.source_root}/resources/css/#{subdir}/*.css"].each do |file|
52
+ m = /^.*\/(.*)\.css$/.match(file)
53
+ sass_file = "#{m.captures[0]}.sass"
54
+ sass_files << "@import '#{File.join(subdir, sass_file)}'"
55
+ create_file(sass_file, ExtJS::Theme.css2sass(file), {:force => true})
56
+ end
57
+ end
58
+ end
59
+ create_file("all.sass", sass_files.join("\n"), {:force => true})
60
+ empty_directory("images")
61
+ FileUtils.cp_r("#{self.class.source_root}/resources/images/default/.", "images")
62
+ end
63
+ end
64
+
65
+ desc "modulate <theme> <hue> <saturation> <lightness>", "Modulate a theme. Specify h, s, l as floats, eg: 1.5"
66
+ def modulate(theme, hue, saturation, lightness)
67
+ ExtJS::Theme.each_image {|img|
68
+ path = img.filename.split('/')
69
+ filename = path.pop
70
+ dir = path.pop
71
+ say_status("modulate", File.join(dir, filename))
72
+ ExtJS::Theme.write_image(img.modulate(lightness.to_f, saturation.to_f, hue.to_f), File.join(ExtJS::Theme["theme_dir"], theme))
73
+ }
74
+ gsub_file(File.join(ExtJS::Theme["theme_dir"], theme, "defines.sass"), /\$hue:\s?(.*)/, "$hue: #{(hue.to_f-1)*180}")
75
+ end
76
+ end
77
+ end
78
+ end
@@ -1,7 +1,7 @@
1
- !bg_color = #eee
2
- !bg_color_ghost = #cbddf3
3
- !border_color = #0f0
4
- !color = #333
5
- !img_path = {{img_path}}
6
- !font = tahoma,arial,verdana,sans-serif
7
- !hue = 0
1
+ $bg_color: #eee
2
+ $bg_color_ghost: #cbddf3
3
+ $border_color: #0f0
4
+ $color: #333
5
+ $img_path:{{img_path}}
6
+ $font: tahoma,arial,verdana,sans-serif
7
+ $hue: 0
@@ -1,3 +1,3 @@
1
1
  ---
2
- :ext_dir: public/javascripts/ext-3.x
3
- :theme_dir: public/stylesheets/themes
2
+ ext_dir: public/javascripts/ext-3.x
3
+ theme_dir: public/stylesheets/themes
@@ -34,7 +34,7 @@ class ThemeTest < Test::Unit::TestCase
34
34
  FileUtils.rm(an_image)
35
35
 
36
36
  # run the effect, it should create a newly modulated version of image (it should be green but how to tell?).
37
- `xtheme effects:modulate foo 1.5 1.0 1.0`
37
+ `xtheme modulate foo 1.5 1.0 1.0`
38
38
 
39
39
  assert File.exists?(an_image), "Failed to modulate images"
40
40
  end
@@ -1,2 +1,2 @@
1
- @import structure/structure.sass
2
- @import visual/visual.sass
1
+ @import 'structure/structure.sass'
2
+ @import 'visual/visual.sass'
@@ -1,7 +1,7 @@
1
- !bg_color = #eee
2
- !bg_color_ghost = #cbddf3
3
- !border_color = #0f0
4
- !color = #333
5
- !img_path = ../themes/foo/images
6
- !font = tahoma,arial,verdana,sans-serif
7
- !hue = 90.0
1
+ $bg_color: #eee
2
+ $bg_color_ghost: #cbddf3
3
+ $border_color: #0f0
4
+ $color: #333
5
+ $img_path:/stylesheets/themes/foo/images
6
+ $font: tahoma,arial,verdana,sans-serif
7
+ $hue: 90.0
@@ -1,3 +1,3 @@
1
- @import ../defines.sass
1
+ @import '../defines.sass'
2
2
  body
3
3
  width: 666px
@@ -1,4 +1,4 @@
1
- @import ../defines.sass
1
+ @import '../defines.sass'
2
2
  body
3
3
  background: black
4
4
 
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 1
8
- - 3
9
- version: 0.1.3
7
+ - 2
8
+ - 0
9
+ version: 0.2.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Christopher Scott
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-04-20 00:00:00 -04:00
17
+ date: 2010-04-21 00:00:00 -04:00
18
18
  default_executable: xtheme
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -69,15 +69,7 @@ files:
69
69
  - Rakefile
70
70
  - bin/xtheme
71
71
  - lib/extjs-theme.rb
72
- - lib/extjs-theme/command.rb
73
- - lib/extjs-theme/commands/base.rb
74
- - lib/extjs-theme/commands/config.rb
75
- - lib/extjs-theme/commands/effects.rb
76
- - lib/extjs-theme/commands/help.rb
77
- - lib/extjs-theme/commands/theme.rb
78
- - lib/extjs-theme/dependencies.rb
79
- - lib/extjs-theme/effects.rb
80
- - lib/extjs-theme/generator.rb
72
+ - lib/extjs-theme/cli.rb
81
73
  - lib/extjs-theme/template/defines.sass
82
74
  - test/config/xtheme.yml
83
75
  - test/extjs-xtheme_test.rb
@@ -1,87 +0,0 @@
1
- require 'yaml'
2
- require 'commands/base'
3
-
4
- Dir["#{File.dirname(__FILE__)}/commands/*"].each { |c| require c }
5
-
6
- module ExtJS::Theme
7
- module Command
8
- class InvalidCommand < RuntimeError;
9
- end
10
- class CommandFailed < RuntimeError;
11
- end
12
- class InvalidConfig < RuntimeError;
13
- end
14
- class ConfigNotFound < RuntimeError;
15
- end
16
-
17
- class << self
18
- def run(command, args, retries=0)
19
- begin
20
- run_internal(command, args.dup)
21
- rescue InvalidCommand
22
- error "Unknown command. Run 'xtheme help' for usage information."
23
- rescue CommandFailed => e
24
- error e.message
25
- rescue InvalidConfig => e
26
- error e.message
27
- rescue ConfigNotFound => e
28
- error e.message
29
- rescue Interrupt => e
30
- error "\n[canceled]"
31
- end
32
- end
33
-
34
- def run_internal(command, args, heroku=nil)
35
- config = load_config
36
-
37
- klass, method = parse(command)
38
-
39
- unless method == "init"
40
- unless config
41
- raise ConfigNotFound.new("Could not locate config file config/xtheme.yml.\nAre you in your application root? Have you run xtheme init?")
42
- end
43
- unless config && File.exists?(config[:ext_dir])
44
- raise InvalidConfig.new("Could not locate ext_dir #{config[:ext_dir]}.\nAre you in your application root?")
45
- end
46
- unless config && File.exists?(config[:theme_dir])
47
- raise InvalidConfig.new("Could not locate theme_dir #{config[:theme_dir]}.\nAre you in your application root?")
48
- end
49
- end
50
-
51
- runner = klass.new(args, config)
52
- raise InvalidCommand unless runner.respond_to?(method)
53
- runner.send(method)
54
- end
55
-
56
- def error(msg)
57
- STDERR.puts(msg)
58
- exit 1
59
- end
60
-
61
- def parse(command)
62
- parts = command.split(':')
63
- case parts.size
64
- when 1
65
- begin
66
- return eval("ExtJS::Theme::Command::#{command.capitalize}"), :index
67
- rescue NameError, NoMethodError
68
- return ExtJS::Theme::Command::Theme, command
69
- end
70
- when 2
71
- begin
72
- return ExtJS::Theme::Command.const_get(parts[0].capitalize), parts[1]
73
- rescue NameError
74
- raise InvalidCommand
75
- end
76
- else
77
- raise InvalidCommand
78
- end
79
- end
80
-
81
- def load_config
82
- FileUtils.mv('.xthemeconfig', 'config/xtheme.yml') if File.exists?('.xthemeconfig')
83
- File.exists?('config/xtheme.yml') ? YAML::load(File.open('config/xtheme.yml')) : nil
84
- end
85
- end
86
- end
87
- end
@@ -1,74 +0,0 @@
1
- require 'fileutils'
2
-
3
- module ExtJS::Theme::Command
4
- class Base
5
- #include Heroku::Helpers
6
-
7
- attr_accessor :args
8
- attr_reader :config
9
-
10
- def initialize(args, config)
11
- @args = args
12
- @config = config
13
- end
14
-
15
- def display(msg, newline=true)
16
- if newline
17
- puts(msg)
18
- else
19
- print(msg)
20
- STDOUT.flush
21
- end
22
- end
23
-
24
- def error(msg)
25
- ExtJS::Theme::Command.error(msg)
26
- end
27
-
28
- def ask
29
- gets.strip
30
- end
31
-
32
- def shell(cmd)
33
- FileUtils.cd(Dir.pwd) {|d| return `#{cmd}`}
34
- end
35
-
36
- def heroku
37
- #@heroku ||= Heroku::Command.run_internal('auth:client', args)
38
- end
39
-
40
- def extract_app(force=true)
41
- app = extract_option('--app')
42
- unless app
43
- app = extract_app_in_dir(Dir.pwd) ||
44
- raise(CommandFailed, "No app specified.\nRun this command from app folder or set it adding --app <app name>") if force
45
- @autodetected_app = true
46
- end
47
- app
48
- end
49
-
50
- def extract_app_in_dir(dir)
51
-
52
- end
53
-
54
- def extract_option(options, default=true)
55
- values = options.is_a?(Array) ? options : [options]
56
- return unless opt_index = args.select { |a| values.include? a }.first
57
- opt_position = args.index(opt_index) + 1
58
- if args.size > opt_position && opt_value = args[opt_position]
59
- if opt_value.include?('--')
60
- opt_value = nil
61
- else
62
- args.delete_at(opt_position)
63
- end
64
- end
65
- opt_value ||= default
66
- args.delete(opt_index)
67
- block_given? ? yield(opt_value) : opt_value
68
- end
69
-
70
- def escape(value)
71
- heroku.escape(value)
72
- end
73
- end
74
- end
@@ -1,57 +0,0 @@
1
- module ExtJS::Theme::Command
2
- class Config < Base
3
- def index
4
- #long = args.delete('--long')
5
- #vars = heroku.config_vars(app)
6
- #display_vars(vars, :long => long)
7
- display "index"
8
- end
9
-
10
- def add
11
- unless args.size > 0 and args.all? { |a| a.include?('=') }
12
- raise CommandFailed, "Usage: xtheme config:add <key>=<value> [<key2>=<value2> ...]"
13
- end
14
-
15
- #vars = args.inject({}) do |vars, arg|
16
- # key, value = arg.split('=', 2)
17
- # vars[key] = value
18
- # vars
19
- #end
20
-
21
- display "Adding config vars:"
22
- #display_vars(vars, :indent => 2)
23
-
24
- #display "Restarting app...", false
25
- #heroku.add_config_vars(app, vars)
26
- #display "done."
27
- end
28
-
29
- def remove
30
- display "Removing #{args.first} and restarting app..."
31
- #heroku.remove_config_var(app, args.first)
32
- display "done."
33
- end
34
-
35
- alias :rm :remove
36
-
37
- def clear
38
- display "Clearing all config vars and restarting app..."
39
- #heroku.clear_config_vars(app)
40
- display "done."
41
- end
42
-
43
- protected
44
- def display_vars(vars, options={})
45
- max_length = vars.map { |v| v[0].size }.max
46
- vars.keys.sort.each do |key|
47
- spaces = ' ' * (max_length - key.size)
48
- display "#{' ' * (options[:indent] || 0)}#{key}#{spaces} => #{format(vars[key], options)}"
49
- end
50
- end
51
-
52
- def format(value, options)
53
- return value if options[:long] || value.size < 36
54
- value[0, 16] + '...' + value[-16, 16]
55
- end
56
- end
57
- end
@@ -1,15 +0,0 @@
1
- module ExtJS::Theme::Command
2
- class Effects < Base
3
-
4
- def modulate
5
- unless @args.length == 4
6
- display "Usage: xtheme effects:modulate <theme-name> <hue> <saturation> <lightness>"
7
- display " Specify <hue>, <saturation> and <lightness> as Floats, for example,"
8
- display " 0.25 means 25%. The default value of each argument is 1.0, that is, 100%"
9
- return
10
- end
11
- display "Modulating theme images"
12
- ExtJS::Theme::Effects.modulate(@config[:ext_dir], "#{@config[:theme_dir]}/#{@args[0]}", @args[1].to_f, @args[2].to_f, @args[3].to_f)
13
- end
14
- end
15
- end
@@ -1,83 +0,0 @@
1
- module ExtJS::Theme::Command
2
- class Help < Base
3
- class HelpGroup < Array
4
- attr_reader :title
5
-
6
- def initialize(title)
7
- @title = title
8
- end
9
-
10
- def command(name, description)
11
- self << [name, description]
12
- end
13
-
14
- def space
15
- self << ['', '']
16
- end
17
- end
18
-
19
- def self.groups
20
- @groups ||= []
21
- end
22
-
23
- def self.group(title, &block)
24
- groups << begin
25
- group = HelpGroup.new(title)
26
- group.instance_eval(&block)
27
- group
28
- end
29
- end
30
-
31
- def self.create_default_groups!
32
- group('General Commands') do
33
- command 'help', 'show this usage'
34
- #command 'version', 'show the gem version'
35
- space
36
- #command 'list', 'list your themes'
37
- command 'create [<name>]', 'create a new theme'
38
- space
39
- #command 'config', 'display the theme\'s config vars (environment)'
40
- #command 'config:add key=val [...]', 'add one or more config vars'
41
- #space
42
- #command 'destroy [<name>]', 'destroy a theme permanently'
43
- end
44
-
45
- group('Effects') do
46
- command 'effects:modulate [<theme> <hue> <saturation> <lightness>]', 'Apply hue, saturation, lightness to a themes\'s images. Specify as Floats, where 1.0 means 100%'
47
- space
48
- end
49
- end
50
-
51
- def index
52
- display usage
53
- end
54
-
55
- def version
56
- #display ExtJS::Theme.version
57
- end
58
-
59
- def usage
60
- longest_command_length = self.class.groups.map do |group|
61
- group.map { |g| g.first.length }
62
- end.flatten.max
63
-
64
- self.class.groups.inject(StringIO.new) do |output, group|
65
- output.puts "=== %s" % group.title
66
- output.puts ''
67
-
68
- group.each do |command, description|
69
- if command.empty?
70
- output.puts ''
71
- else
72
- output.puts "%-*s # %s" % [longest_command_length, command, description]
73
- end
74
- end
75
-
76
- output.puts ''
77
- output
78
- end.string
79
- end
80
- end
81
- end
82
-
83
- ExtJS::Theme::Command::Help.create_default_groups!
@@ -1,47 +0,0 @@
1
- require 'yaml'
2
-
3
- module ExtJS::Theme::Command
4
- class Theme < Base
5
-
6
- def init
7
-
8
- ext_path = args[0] || 'public/javascripts/ext-3.2.0'
9
- theme_path = args[1] || 'app/stylesheets/themes'
10
-
11
- unless File.directory?(ext_path)
12
- return display "Error: invalid ext js path: #{ext_path}"
13
- end
14
-
15
- unless File.directory?(theme_path)
16
- FileUtils.mkdir_p(theme_path)
17
- display "Create theme directory #{theme_path}"
18
- end
19
-
20
- display "Initializing xtheme configuration file config/xtheme.yml"
21
- File.open("config/xtheme.yml", "w+") {|f|
22
- f << {
23
- :ext_dir => ext_path,
24
- :theme_dir => theme_path
25
- }.to_yaml
26
- }
27
- end
28
-
29
- def list
30
- display "Not implemented"
31
- end
32
-
33
- def create
34
- name = args.shift.downcase.strip rescue nil
35
- if !name
36
- return display "Usage: xtheme create <name>"
37
- end
38
- ExtJS::Theme::Generator.create(name, @config[:ext_dir], @config[:theme_dir])
39
- display "Created #{name}"
40
-
41
- end
42
-
43
- def destroy
44
- display "Not implemented"
45
- end
46
- end
47
- end
@@ -1,18 +0,0 @@
1
- begin
2
- gem 'haml-edge', '>= 2.3.0'
3
- $stderr.puts "Loading haml-edge gem."
4
- rescue LoadError
5
- #pass
6
- end
7
-
8
- begin
9
- gem 'rmagick'
10
- $stderr.puts "Loading rmagick gem."
11
-
12
- rescue LoadError
13
- #pass
14
- end
15
-
16
- require 'sass'
17
- require 'RMagick'
18
-
@@ -1,57 +0,0 @@
1
- module ExtJS::Theme
2
- module Effects
3
-
4
- ##
5
- # performs hsv transformation on Ext theme images and save to Sass theme dir.
6
- # @param {String} name Theme name
7
- # @param {String} ext_dir path to Ext directory relative to public/javascripts
8
- # @param {Float} hue
9
- # @param {Float} saturation
10
- # @param {Float} lightness
11
- #
12
- def self.modulate(ext_dir, theme_dir, hue=1.0, saturation=1.0, lightness=1.0)
13
- each_image("#{ext_dir}/resources/images/default") {|img|
14
- write_image(img.modulate(lightness, saturation, hue), theme_dir)
15
- }
16
- # update hue in defines.sass
17
- defines = File.read("#{theme_dir}/defines.sass")
18
- File.open("#{theme_dir}/defines.sass", "w+") {|f| f << defines.gsub(/hue\s?=.*/, "hue = #{(hue-1)*180}") }
19
- end
20
-
21
- private
22
-
23
- ##
24
- # Iterate all theme images
25
- # @param {String} path
26
- #
27
- def self.each_image(path)
28
- Dir["#{path}/*/"].each do |dir|
29
- Dir[dir+'/*.gif'].each do |filename|
30
- yield(Magick::ImageList.new(filename))
31
- end
32
- Dir[dir+'/*.png'].each do |filename|
33
- yield(Magick::ImageList.new(filename))
34
- end
35
- end
36
- # Now transform any images left in the base /images/default directory (excluding s.gif)
37
- Dir["#{path}/*.*"].reject {|f| f.match('s.gif')}.each do |filename|
38
- yield(Magick::ImageList.new(filename))
39
- end
40
- end
41
-
42
- ##
43
- # Write transformed RMagick::Image to theme directory
44
- # @param {RMagick::Image} img
45
- # @param {String} dest Theme directory
46
- #
47
- def self.write_image(img, dest)
48
- # Get filename and directory
49
- m = /\/default\/(.*)\/(.*)\.(.*)$/.match(img.filename) || /\/default\/(.*)\.(.*)$/.match(img.filename)
50
- #m = /\/(.*)\/(.*)\.(.*)$/.match(img.filename) || /\/(.*)\.(.*)$/.match(img.filename)
51
- outfile = (m.captures.length == 3) ? "#{dest}/images/#{m[1]}#{m[2]}.#{m[3]}" : "#{dest}/images/#{m[1]}.#{m[2]}"
52
-
53
- puts " - #{outfile}"
54
- img.write(outfile)
55
- end
56
- end
57
- end
@@ -1,98 +0,0 @@
1
- module ExtJS
2
- module Theme
3
- module Generator
4
- ##
5
- # creates a new Sass theme
6
- # @param {String} name
7
- # @param {String} ext_dir path to Ext directory relative to public/javascripts
8
- # @param {String} theme_dir Path to theme output dir (eg: stylesheets/sass)
9
- #
10
- def self.create(name, ext_dir, theme_dir)
11
- ext_css_path = "#{ext_dir}/resources/css"
12
- theme_path = "#{theme_dir}/#{name}"
13
-
14
- # Create theme directory in /stylesheets/sass
15
- FileUtils.mkdir_p ["#{theme_path}/visual", "#{theme_path}/structure"]
16
-
17
- # Create the defines.sass file, set img_path variable.
18
- FileUtils.copy("#{File.dirname(__FILE__)}/template/defines.sass", "#{theme_path}/defines.sass")
19
- defines = File.read("#{theme_path}/defines.sass")
20
- File.open("#{theme_path}/defines.sass", "w+") {|f| f << defines.gsub(/\{\{img_path\}\}/, "../themes/#{name}/images") }
21
- puts " - created #{theme_path}/defines.sass"
22
-
23
- sass_files = []
24
- # Iterate each Ext css file and convert to Sass.
25
- ["structure", "visual"].each do |subdir|
26
- puts " Converting #{subdir} styles to Sass"
27
- Dir["#{ext_css_path}/#{subdir}/*.css"].each do |file|
28
- m = /^.*\/(.*)\.css$/.match(file)
29
- sass_file = "#{theme_path}/#{subdir}/#{m.captures[0]}.sass"
30
- puts " - sass-convert #{m.captures[0]}.css -> #{sass_file}"
31
- sass_files << "@import #{subdir}/#{m.captures[0]}.sass"
32
- `sass-convert #{file} #{sass_file}`
33
- write_sass_vars(sass_file)
34
- end
35
- end
36
-
37
- # Create master sass file, which includes @imports for all other files in theme.
38
- puts " - Writing all.sass"
39
- f = File.new("#{theme_path}/all.sass", "w")
40
- f.puts sass_files.join("\n")
41
-
42
- # Copy Ext theme images to new Sass theme dir.
43
- FileUtils.cp_r("#{ext_dir}/resources/images/default", "#{theme_path}/images")
44
- end
45
-
46
-
47
- private
48
-
49
- ##
50
- # Iterate all theme images
51
- # @param {String} path
52
- #
53
- def self.each_image(path)
54
- Dir["#{path}/*/"].each do |dir|
55
- Dir[dir+'/*.gif'].each do |filename|
56
- yield(Magick::ImageList.new(filename))
57
- end
58
- Dir[dir+'/*.png'].each do |filename|
59
- yield(Magick::ImageList.new(filename))
60
- end
61
- end
62
- # Now transform any images left in the base /images/default directory (excluding s.gif)
63
- Dir["#{path}/*.*"].reject {|f| f.match('s.gif')}.each do |filename|
64
- yield(Magick::ImageList.new(filename))
65
- end
66
- end
67
-
68
- ##
69
- # Searches .sass file for HEX colors and wraps in Sass adjust_hue function.
70
- # Also substitutes urls with !img_path Sass var
71
- # @param {String} filename of .sass file to write !vars to
72
- #
73
- def self.write_sass_vars(file)
74
- sass = File.read(file)
75
- sass.gsub!(/background-image: url\(\.\.\/images\/default/, 'background-image = url(!img_path')
76
- sass.gsub!(/\b(.*):\s?#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/, '\1 = adjust_hue(#\2, !hue)')
77
-
78
- # append @import "defines.sass" at start of each .sass file in order to use defined variables
79
- File.open(file, "w") {|f| f << "@import ../defines.sass\n#{sass}" }
80
- end
81
-
82
- ##
83
- # Write transformed RMagick::Image to theme directory
84
- # @param {RMagick::Image} img
85
- # @param {String} dest Theme directory
86
- #
87
- def self.write_image(img, dest)
88
- # Get filename and directory
89
- m = /\/default\/(.*)\/(.*)\.(.*)$/.match(img.filename) || /\/default\/(.*)\.(.*)$/.match(img.filename)
90
- #m = /\/(.*)\/(.*)\.(.*)$/.match(img.filename) || /\/(.*)\.(.*)$/.match(img.filename)
91
- outfile = (m.captures.length == 3) ? "#{dest}/images/#{m[1]}#{m[2]}.#{m[3]}" : "#{dest}/images/#{m[1]}.#{m[2]}"
92
-
93
- puts " - #{outfile}"
94
- img.write(outfile)
95
- end
96
- end
97
- end
98
- end