extjs-theme 0.1.3 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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