extjs-theme 0.1.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.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Christocracy
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
File without changes
data/README.rdoc ADDED
@@ -0,0 +1,75 @@
1
+ = extjs-theme
2
+
3
+ Generates a Sass version of Ext theme. Includes methods for colorizing images.
4
+
5
+ This Gem depends upon RMagick[http://gemcutter.org/gems/rmagick] and haml-edge[http://gemcutter.org/gems/haml-edge]
6
+
7
+ == Installation
8
+
9
+ The Gem is hosted at Gemcutter[http://gemcutter.com]. Install the gem with:
10
+
11
+ sudo gem install extjs-theme
12
+
13
+ == Usage
14
+
15
+ In the root of your Rails app, first execute the following in your console:
16
+
17
+ $ xtheme init <path/to/ext> <path/to/stylesheets>
18
+
19
+ This creates a YAML config file named .xthemeconfig in the application root.
20
+
21
+ ---
22
+ theme_dir: public/stylesheets/sass
23
+ ext_dir: public/javascripts/ext-3.1.0
24
+
25
+ Example
26
+
27
+ $ xtheme init public/javascripts/ext-3.1.0 public/stylesheets
28
+
29
+ To generate a new Sass theme:
30
+
31
+ $ xtheme create my-theme
32
+
33
+ In Rails, this will have created a new directory <code>public/stylesheets/sass/my-theme</code>
34
+
35
+ The generator creates a main include file called <code>my-theme/init.sass</code> (TODO: change to <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/init.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.
36
+
37
+ =stylesheet_link_tag "my-theme/init"
38
+
39
+ or in an <code>erb</code> template:
40
+
41
+ <%= stylesheet_link_tag "my-theme/init"
42
+
43
+ The generator also creates a copy of all the Ext theme images in <code>my-theme/images</code>
44
+
45
+ Another important sass file created is <code>my-theme/defines.sass</code>. This file contains Sass variable declarations added to each Ext sass file.
46
+
47
+ !img_path = ../sass/my-theme/images
48
+ !font = tahoma,arial,verdana,sans-serif
49
+ !hue = -90.0
50
+
51
+ Form more on Haml and Sass, consult the HAML documentation[http://haml-lang.com/] to learn about including Sass[http://sass-lang.com/] stylesheets.
52
+
53
+ == Effects
54
+
55
+ The Gem includes commands for theme colorization, including image-processing through RMagick.
56
+
57
+ 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]:
58
+
59
+ $ xtheme effects:modulate <theme-name> <hue> <saturation> <lightness>
60
+
61
+ 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]
62
+
63
+ Based upon the default blue Ext theme, the following will generate a pink theme:
64
+
65
+ $ xtheme effects:modulate my-theme 0.5 1.0 1.0
66
+
67
+ A green theme:
68
+
69
+ $ xtheme effects:modulate my-theme 1.5 1.0 1.0
70
+
71
+ *Only hue works currently, saturation and lightness are under development*
72
+
73
+ == Copyright
74
+
75
+ Copyright (c) 2010 Christocracy. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,63 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "extjs-theme"
8
+ gem.summary = %Q{Ext theme-generator and colorizer}
9
+ gem.description = %Q{Generates Sass-based Ext themes. Includes methods for colorizing themes.}
10
+ gem.email = "christocracy@gmail.com"
11
+ gem.homepage = "http://github.com/extjs/extjs-theme"
12
+ gem.authors = ["Christopher Scott"]
13
+ gem.add_development_dependency "thoughtbot-shoulda"
14
+ gem.add_dependency "rmagick"
15
+ gem.add_dependency "haml-edge", ">=2.3"
16
+ gem.files = %w(Rakefile) +
17
+ Dir.glob("{bin,lib,test}/**/*")
18
+
19
+
20
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
21
+ end
22
+ Jeweler::GemcutterTasks.new
23
+ rescue LoadError
24
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
25
+ end
26
+
27
+ require 'rake/testtask'
28
+ Rake::TestTask.new(:test) do |test|
29
+ test.libs << 'lib' << 'test'
30
+ test.pattern = 'test/**/*_test.rb'
31
+ test.verbose = true
32
+ end
33
+
34
+ begin
35
+ require 'rcov/rcovtask'
36
+ Rcov::RcovTask.new do |test|
37
+ test.libs << 'test'
38
+ test.pattern = 'test/**/*_test.rb'
39
+ test.verbose = true
40
+ end
41
+ rescue LoadError
42
+ task :rcov do
43
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
44
+ end
45
+ end
46
+
47
+ task :test => :check_dependencies
48
+
49
+ task :default => :test
50
+
51
+ require 'rake/rdoctask'
52
+ Rake::RDocTask.new do |rdoc|
53
+ if File.exist?('VERSION')
54
+ version = File.read('VERSION')
55
+ else
56
+ version = ""
57
+ end
58
+
59
+ rdoc.rdoc_dir = 'rdoc'
60
+ rdoc.title = "extjs-xtheme #{version}"
61
+ rdoc.rdoc_files.include('README*')
62
+ rdoc.rdoc_files.include('lib/**/*.rb')
63
+ end
data/bin/xtheme ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+
5
+ $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../lib')
6
+
7
+ require 'extjs-theme'
8
+ require 'extjs-theme/command'
9
+
10
+ args = ARGV.dup
11
+ ARGV.clear
12
+ command = args.shift.strip rescue 'help'
13
+
14
+ ExtJS::Theme::Command.run(command, args)
@@ -0,0 +1,13 @@
1
+ ##
2
+ # XTheme
3
+ # A module for generating and colorizing ExtJS themes.
4
+ #
5
+ module ExtJS
6
+ module Theme
7
+ end
8
+ end
9
+ $LOAD_PATH.unshift(File.dirname(__FILE__) + '/extjs-theme')
10
+
11
+ ['dependencies', 'generator', 'effects'].each do |file|
12
+ require file
13
+ end
@@ -0,0 +1,81 @@
1
+ require 'commands/base'
2
+
3
+ Dir["#{File.dirname(__FILE__)}/commands/*"].each { |c| require c }
4
+
5
+ module ExtJS::Theme
6
+ module Command
7
+ class InvalidCommand < RuntimeError; end
8
+ class CommandFailed < RuntimeError; end
9
+ class InvalidConfig < RuntimeError; end
10
+ class ConfigNotFound < RuntimeError; end
11
+
12
+ class << self
13
+ def run(command, args, retries=0)
14
+ begin
15
+ run_internal(command, args.dup)
16
+ rescue InvalidCommand
17
+ error "Unknown command. Run 'xtheme help' for usage information."
18
+ rescue CommandFailed => e
19
+ error e.message
20
+ rescue InvalidConfig => e
21
+ error e.message
22
+ rescue ConfigNotFound => e
23
+ error e.message
24
+ rescue Interrupt => e
25
+ error "\n[canceled]"
26
+ end
27
+ end
28
+
29
+ def run_internal(command, args, heroku=nil)
30
+ config = load_config
31
+
32
+ klass, method = parse(command)
33
+
34
+ unless method == "init"
35
+ unless config
36
+ raise ConfigNotFound.new("Could not locate config file .xthemeconfig.\nAre you in your application root? Have you run xtheme init?")
37
+ end
38
+ unless config && File.exists?(config[:ext_dir])
39
+ raise InvalidConfig.new("Could not locate ext_dir #{config[:ext_dir]}.\nAre you in your application root?")
40
+ end
41
+ unless config && File.exists?(config[:theme_dir])
42
+ raise InvalidConig.new("Could not locate theme_dir #{config[:theme_dir]}.\nAre you in your application root?")
43
+ end
44
+ end
45
+
46
+ runner = klass.new(args, config)
47
+ raise InvalidCommand unless runner.respond_to?(method)
48
+ runner.send(method)
49
+ end
50
+
51
+ def error(msg)
52
+ STDERR.puts(msg)
53
+ exit 1
54
+ end
55
+
56
+ def parse(command)
57
+ parts = command.split(':')
58
+ case parts.size
59
+ when 1
60
+ begin
61
+ return eval("ExtJS::Theme::Command::#{command.capitalize}"), :index
62
+ rescue NameError, NoMethodError
63
+ return ExtJS::Theme::Command::Theme, command
64
+ end
65
+ when 2
66
+ begin
67
+ return ExtJS::Theme::Command.const_get(parts[0].capitalize), parts[1]
68
+ rescue NameError
69
+ raise InvalidCommand
70
+ end
71
+ else
72
+ raise InvalidCommand
73
+ end
74
+ end
75
+
76
+ def load_config
77
+ File.exists?('.xthemeconfig') ? YAML::load(File.open('.xthemeconfig')) : nil
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,74 @@
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
@@ -0,0 +1,56 @@
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...", false
31
+ #heroku.remove_config_var(app, args.first)
32
+ display "done."
33
+ end
34
+ alias :rm :remove
35
+
36
+ def clear
37
+ display "Clearing all config vars and restarting app...", false
38
+ #heroku.clear_config_vars(app)
39
+ display "done."
40
+ end
41
+
42
+ protected
43
+ def display_vars(vars, options={})
44
+ max_length = vars.map { |v| v[0].size }.max
45
+ vars.keys.sort.each do |key|
46
+ spaces = ' ' * (max_length - key.size)
47
+ display "#{' ' * (options[:indent] || 0)}#{key}#{spaces} => #{format(vars[key], options)}"
48
+ end
49
+ end
50
+
51
+ def format(value, options)
52
+ return value if options[:long] || value.size < 36
53
+ value[0, 16] + '...' + value[-16, 16]
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,17 @@
1
+ require 'launchy'
2
+
3
+ module ExtJS::Theme::Command
4
+ class Effects < Base
5
+
6
+ def modulate
7
+ unless @args.length == 4
8
+ display "Usage: xtheme effects:modulate <theme-name> <hue> <saturation> <lightness>"
9
+ display " Specify <hue>, <saturation> and <lightness> as Floats, for example,"
10
+ display " 0.25 means 25%. The default value of each argument is 1.0, that is, 100%"
11
+ return
12
+ end
13
+ display "Modulating theme images"
14
+ ExtJS::Theme::Effects.modulate(@config[:ext_dir], "#{@config[:theme_dir]}/#{@args[0]}", @args[1].to_f, @args[2].to_f, @args[3].to_f)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,83 @@
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!
@@ -0,0 +1,49 @@
1
+ require 'launchy'
2
+
3
+ module ExtJS::Theme::Command
4
+ class Theme < Base
5
+
6
+ def init
7
+
8
+ unless args.length == 2
9
+ display "Usage: xtheme init <path/to/ext> <path/to/stylesheets>"
10
+ display " - Eg: xtheme init public/javascripts/ext-3.1.0 public/stylesheets"
11
+ return
12
+ end
13
+
14
+ unless File.directory?(args[0])
15
+ return display "Error: invalid path/to/ext #{args[0]}"
16
+ end
17
+ unless File.directory?(args[1])
18
+ return display "Error: invalid path/to/stylesheets #{args[1]}"
19
+ end
20
+
21
+ display "Initializing xtheme configuration file .xthemeconfig"
22
+
23
+ File.open(".xthemeconfig", "w+") {|f|
24
+ f << {
25
+ :ext_dir => args[0],
26
+ :theme_dir => "#{args[1]}/sass"
27
+ }.to_yaml
28
+ }
29
+ end
30
+
31
+ def list
32
+ display "Not implemented"
33
+ end
34
+
35
+ def create
36
+ name = args.shift.downcase.strip rescue nil
37
+ if !name
38
+ return display "Usage: xtheme create <name>"
39
+ end
40
+ ExtJS::Theme::Generator.create(name, @config[:ext_dir], @config[:theme_dir])
41
+ display "Created #{name}"
42
+
43
+ end
44
+
45
+ def destroy
46
+ display "Not implemented"
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,16 @@
1
+ begin
2
+ gem 'haml-edge', '>= 2.3.0'
3
+ $stderr.puts "Loading haml-edge gem."
4
+
5
+ gem 'rmagick'
6
+ $stderr.puts "Loading rmagick gem."
7
+
8
+ rescue Exception
9
+ #pass
10
+ end
11
+
12
+ require 'sass'
13
+ require 'rmagick'
14
+
15
+
16
+
@@ -0,0 +1,57 @@
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} lightneess
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
@@ -0,0 +1,116 @@
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\}\}/, "../sass/#{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 " - css2sass #{m.captures[0]}.css -> #{sass_file}"
31
+ sass_files << "@import #{subdir}/#{m.captures[0]}.sass"
32
+ `css2sass #{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 init.sass"
39
+ f = File.new("#{theme_path}/init.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
+ # performs hsv transformation on Ext theme images and save to Sass theme dir.
48
+ # @param {String} name Theme name
49
+ # @param {String} ext_dir path to Ext directory relative to public/javascripts
50
+ # @param {Float} hue
51
+ # @param {Float} saturation
52
+ # @param {Float} lightneess
53
+ #
54
+ def self.hsv_transform(name, ext_dir, theme_dir, hue=1.0, saturation=1.0, lightness=1.0)
55
+ theme_path = "#{theme_dir}/#{name}"
56
+
57
+ each_image(ext_path) {|img|
58
+ write_image(img.modulate(lightness, saturation, hue), theme_path(name))
59
+ }
60
+ # update hue in defines.sass
61
+ defines = File.read("#{theme_path}/defines.sass")
62
+ File.open("#{theme_path}/defines.sass", "w+") {|f| f << defines.gsub(/hue\s?=.*/, "hue = #{(hue-1)*180}") }
63
+ end
64
+
65
+ private
66
+
67
+ ##
68
+ # Iterate all theme images
69
+ # @param {String} path
70
+ #
71
+ def self.each_image(path)
72
+ Dir["#{path}/*/"].each do |dir|
73
+ Dir[dir+'/*.gif'].each do |filename|
74
+ yield(Magick::ImageList.new(filename))
75
+ end
76
+ Dir[dir+'/*.png'].each do |filename|
77
+ yield(Magick::ImageList.new(filename))
78
+ end
79
+ end
80
+ # Now transform any images left in the base /images/default directory (excluding s.gif)
81
+ Dir["#{path}/*.*"].reject {|f| f.match('s.gif')}.each do |filename|
82
+ yield(Magick::ImageList.new(filename))
83
+ end
84
+ end
85
+
86
+ ##
87
+ # Searches .sass file for HEX colors and wraps in Sass adjust_hue function.
88
+ # Also substitutes urls with !img_path Sass var
89
+ # @param {String} filename of .sass file to write !vars to
90
+ #
91
+ def self.write_sass_vars(file)
92
+ sass = File.read(file)
93
+ sass.gsub!(/background-image: url\(\.\.\/images\/default/, 'background-image = url(!img_path')
94
+ sass.gsub!(/\b(.*):\s?#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/, '\1 = adjust_hue(#\2, !hue)')
95
+
96
+ # append @import "defines.sass" at start of each .sass file in order to use defined variables
97
+ File.open(file, "w") {|f| f << "@import ../defines.sass\n#{sass}" }
98
+ end
99
+
100
+ ##
101
+ # Write transformed RMagick::Image to theme directory
102
+ # @param {RMagick::Image} img
103
+ # @param {String} dest Theme directory
104
+ #
105
+ def self.write_image(img, dest)
106
+ # Get filename and directory
107
+ m = /\/default\/(.*)\/(.*)\.(.*)$/.match(img.filename) || /\/default\/(.*)\.(.*)$/.match(img.filename)
108
+ #m = /\/(.*)\/(.*)\.(.*)$/.match(img.filename) || /\/(.*)\.(.*)$/.match(img.filename)
109
+ outfile = (m.captures.length == 3) ? "#{dest}/images/#{m[1]}#{m[2]}.#{m[3]}" : "#{dest}/images/#{m[1]}.#{m[2]}"
110
+
111
+ puts " - #{outfile}"
112
+ img.write(outfile)
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +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
@@ -0,0 +1,7 @@
1
+ require 'test_helper'
2
+
3
+ class ExtjsXthemeTest < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'extjs-xtheme'
8
+
9
+ class Test::Unit::TestCase
10
+ end
metadata ADDED
@@ -0,0 +1,104 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: extjs-theme
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Christopher Scott
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-02-12 00:00:00 -05:00
13
+ default_executable: xtheme
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: thoughtbot-shoulda
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: rmagick
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: haml-edge
37
+ type: :runtime
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: "2.3"
44
+ version:
45
+ description: Generates Sass-based Ext themes. Includes methods for colorizing themes.
46
+ email: christocracy@gmail.com
47
+ executables:
48
+ - xtheme
49
+ extensions: []
50
+
51
+ extra_rdoc_files:
52
+ - LICENSE
53
+ - README
54
+ - README.rdoc
55
+ files:
56
+ - Rakefile
57
+ - bin/xtheme
58
+ - lib/extjs-theme.rb
59
+ - lib/extjs-theme/command.rb
60
+ - lib/extjs-theme/commands/base.rb
61
+ - lib/extjs-theme/commands/conifg.rb
62
+ - lib/extjs-theme/commands/effects.rb
63
+ - lib/extjs-theme/commands/help.rb
64
+ - lib/extjs-theme/commands/theme.rb
65
+ - lib/extjs-theme/dependencies.rb
66
+ - lib/extjs-theme/effects.rb
67
+ - lib/extjs-theme/generator.rb
68
+ - lib/extjs-theme/template/defines.sass
69
+ - test/extjs-xtheme_test.rb
70
+ - test/test_helper.rb
71
+ - LICENSE
72
+ - README
73
+ - README.rdoc
74
+ has_rdoc: true
75
+ homepage: http://github.com/extjs/extjs-theme
76
+ licenses: []
77
+
78
+ post_install_message:
79
+ rdoc_options:
80
+ - --charset=UTF-8
81
+ require_paths:
82
+ - lib
83
+ required_ruby_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: "0"
88
+ version:
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: "0"
94
+ version:
95
+ requirements: []
96
+
97
+ rubyforge_project:
98
+ rubygems_version: 1.3.5
99
+ signing_key:
100
+ specification_version: 3
101
+ summary: Ext theme-generator and colorizer
102
+ test_files:
103
+ - test/extjs-xtheme_test.rb
104
+ - test/test_helper.rb