about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorhut <hut@lavabit.com>2009-06-12 02:30:39 +0200
committerhut <hut@lavabit.com>2009-06-12 02:30:39 +0200
commit8f8b66aa27050f29b06ee66ed9c86308089fae4a (patch)
treeaedc4f63dc70a681696e213166d41f277891569b
parent8a6f5eab0b884acd58ed86c00a30b57901442be6 (diff)
downloadranger-8f8b66aa27050f29b06ee66ed9c86308089fae4a.tar.gz
implementing colorschemes, work in progress
-rw-r--r--code/cli.rb108
-rw-r--r--code/color.rb141
-rw-r--r--code/draw.rb205
-rw-r--r--data/colorscheme/default.rb11
-rwxr-xr-xranger.rb1
5 files changed, 321 insertions, 145 deletions
diff --git a/code/cli.rb b/code/cli.rb
index 0f915634..12561e36 100644
--- a/code/cli.rb
+++ b/code/cli.rb
@@ -104,39 +104,57 @@ module CLI
 		end
 	end
 
-	def color(fg = -1, bg = -1)
-		if OPTIONS['color']
-			Ncurses.color_set(get_color(fg,bg), nil)
-		end
-	end
-
-	def color_at y, x=0, len=-1, fg=-1, bg=-1, attributes=0
-		if OPTIONS['color']
-			if y < 0 then y += Ncurses.LINES end
-			Ncurses.mvchgat(y, x, len, attributes, get_color(fg, bg), nil)
-		end
-	end
-
-	def color_bold_at y, x=0, len=-1, fg=-1, bg=-1
-		color_at(y, x, len, fg, bg, attributes = Ncurses::A_BOLD)
-	end
-
-	def color_reverse_bold_at y, x=0, len=-1, fg=-1, bg=-1
-		if OPTIONS['color']
-			color_at(y, x, len, fg, bg, Ncurses::A_REVERSE | Ncurses::A_BOLD)
+	def attr_set(fg=-1, bg=-1, attr = nil)
+		fg, bg, attr = fg if fg.is_a? Array
+		if attr
+			Ncurses.attrset(attr | Ncurses.COLOR_PAIR(get_color(fg, bg)))
 		else
-			Ncurses.mvchgat(y, x, len, Ncurses::A_REVERSE | Ncurses::A_BOLD, 0, nil)
+			Ncurses.color_set(get_color(fg, bg), nil)
 		end
 	end
-	alias color_bold_reverse_at color_reverse_bold_at
 
-	def color_reverse_at y, x=0, len=-1, fg=-1, bg=-1
-		if OPTIONS['color']
-			color_at(y, x, len, fg, bg, Ncurses::A_REVERSE)
-		else
-			Ncurses.mvchgat(y, x, len, Ncurses::A_REVERSE, 0, nil)
-		end
-	end
+	def attr_at(y=0, x=0, len=-1, fg=-1, bg=-1, attr=0)
+		fg, bg, attr = fg if fg.is_a? Array
+		y += lines if y < 0
+		x += cols if x < 0
+		attr ||= 0
+
+		Ncurses.mvchgat(y, x, len, attr, get_color(fg, bg), nil)
+	end
+
+#	def color(fg = -1, bg = -1)
+#		if OPTIONS['color']
+#			Ncurses.color_set(get_color(fg,bg), nil)
+#		end
+#	end
+#
+#	def color_at y, x=0, len=-1, fg=-1, bg=-1, attributes=0
+#		if OPTIONS['color']
+#			if y < 0 then y += Ncurses.LINES end
+#			Ncurses.mvchgat(y, x, len, attributes, get_color(fg, bg), nil)
+#		end
+#	end
+#
+#	def color_bold_at y, x=0, len=-1, fg=-1, bg=-1
+#		color_at(y, x, len, fg, bg, attributes = Ncurses::A_BOLD)
+#	end
+#
+#	def color_reverse_bold_at y, x=0, len=-1, fg=-1, bg=-1
+#		if OPTIONS['color']
+#			color_at(y, x, len, fg, bg, Ncurses::A_REVERSE | Ncurses::A_BOLD)
+#		else
+#			Ncurses.mvchgat(y, x, len, Ncurses::A_REVERSE | Ncurses::A_BOLD, 0, nil)
+#		end
+#	end
+#	alias color_bold_reverse_at color_reverse_bold_at
+#
+#	def color_reverse_at y, x=0, len=-1, fg=-1, bg=-1
+#		if OPTIONS['color']
+#			color_at(y, x, len, fg, bg, Ncurses::A_REVERSE)
+#		else
+#			Ncurses.mvchgat(y, x, len, Ncurses::A_REVERSE, 0, nil)
+#		end
+#	end
 
 	def get_color(fg, bg)
 		n = bg+2 + 9*(fg+2)
@@ -149,20 +167,20 @@ module CLI
 		end
 		return color
 	end
-
-	def bold(b = true)
-		if b
-			Ncurses.attron(Ncurses::A_BOLD) 
-		else
-			Ncurses.attroff(Ncurses::A_BOLD) 
-		end
-	end
-
-	def reverse(b = true)
-		if b
-			Ncurses.attron(Ncurses::A_REVERSE) 
-		else
-			Ncurses.attroff(Ncurses::A_REVERSE) 
-		end
-	end
+#
+#	def bold(b = true)
+#		if b
+#			Ncurses.attron(Ncurses::A_BOLD) 
+#		else
+#			Ncurses.attroff(Ncurses::A_BOLD) 
+#		end
+#	end
+#
+#	def reverse(b = true)
+#		if b
+#			Ncurses.attron(Ncurses::A_REVERSE) 
+#		else
+#			Ncurses.attroff(Ncurses::A_REVERSE) 
+#		end
+#	end
 end
diff --git a/code/color.rb b/code/color.rb
new file mode 100644
index 00000000..244ec127
--- /dev/null
+++ b/code/color.rb
@@ -0,0 +1,141 @@
+require 'ncurses'
+require 'code/debug'
+
+module Color
+	extend Color
+
+	COLORSCHEMEDIR = File.join(MYDIR, 'data', 'colorscheme')
+	def load_colorscheme(name)
+		## colorschemes are located in data/colorscheme/
+		fname = File.join(COLORSCHEMEDIR, "#{name}.rb")
+#		assert File.exists?(fname), "No such colorscheme: #{fname}"
+		
+		clear_all
+		load fname
+		::Console.write("Colorscheme #{name} loaded.")
+	end
+
+	def clear_all()
+		clear
+		for key, type in TYPES
+			type.clear
+		end
+	end
+
+	def clear
+		for var in instance_variables
+			instance_variable_set(var, nil)
+		end
+	end
+
+	def default() -1 end
+	def black()    0 end
+	def red()      1 end
+	def green()    2 end
+	def yellow()   3 end
+	def blue()     4 end
+	def magenta()  5 end
+	def cyan()     6 end
+	def white()    7 end
+
+	alias df default
+	alias brown yellow
+	alias orange yellow
+	alias purlpe magenta
+	alias pink magenta
+	alias teal cyan
+	alias gray white
+	alias grey white
+
+	def none()       Ncurses::A_NORMAL     end
+	def bold()       Ncurses::A_BOLD       end
+	def reverse()    Ncurses::A_REVERSE    end
+	def underline()  Ncurses::A_UNDERLINE  end
+
+	def standout()   Ncurses::A_STANDOUT   end
+	def blink()      Ncurses::A_BLINK      end
+	def dim()        Ncurses::A_DIM        end
+	def protect()    Ncurses::A_PROTECT    end
+	def invisible()  Ncurses::A_INVIS      end
+	def altcharset() Ncurses::A_ALTCHARSET end
+	def chartext()   Ncurses::A_CHARTEXT   end
+
+	alias reversed reverse
+	alias revert reverse
+	alias invis invisible
+
+	def default_color() return default, default, none end
+	alias dc default_color
+
+	## a shortcut.
+	##    use %w{txt type left_side}
+	## is equivalent to:
+	##    def txt() @txt || @type || @left_side || @base end
+	def self.use(arr)
+		arr << 'base' unless arr.last == 'base'
+		body = arr.map{|x| "@#{x}"}.join(' || ')
+		eval "def #{arr.first}() #{body} end"
+	end
+
+	use %w{base}
+	use %w{file}
+
+	use %w{link file}
+	use %w{badlink file}
+	use %w{goodlink file}
+	use %w{directory file}
+	use %w{forbidden directory file}
+
+
+	use %w{media file}
+	use %w{video media file}
+	use %w{sound media file}
+	use %w{image media file}
+	use %w{executable file}
+	use %w{script executable file}
+	use %w{binary executable file}
+
+	def content!() @content end
+
+	module Type
+		include Color
+
+		ATTRIBUTES = %w[
+			base file directory media executable
+			video sound image
+			script binary
+
+			terminal_cursor error info
+		]
+
+		for a in ATTRIBUTES
+			eval <<-DONE
+				def #{a}()
+					@#{a}_cache ||= @#{a} || super || Color.#{a} || default_color
+				end
+			DONE
+		end
+
+		## this is only meant to be used in Color
+		def clear_all() nil end
+	end
+
+	module Normal;   extend Type end
+	module Selected; extend Type end
+	module Marked;   extend Type end
+	module Console;  extend Type end
+
+	TYPES = {
+		:normal   => Normal,
+		:selected => Selected,
+		:marked   => Marked,
+		:console  => Console
+	}
+
+	def [](x)      TYPES[x] end
+	def selected() Selected end
+	def normal()   Normal   end
+	def marked()   Marked   end
+	def console()  Console  end
+end
+
diff --git a/code/draw.rb b/code/draw.rb
index 36688642..8efc5135 100644
--- a/code/draw.rb
+++ b/code/draw.rb
@@ -1,12 +1,11 @@
 module Fm
 	DONT_PREVIEW_THESE_FILES = /\.(avi|[mj]pe?g|iso|mp\d|og[gmv]|wm[av]|mkv|torrent|so|class|flv|png|bmp|vob|divx?)$/i
 
-	def self.column_put_file(n, file)
+	def column_put_file(n, file)
 		i = 0
 		if OPTIONS['filepreview'] and file.path !~ DONT_PREVIEW_THESE_FILES
 			m = lines - 2
-			color 7
-			bold false
+			attr_set(Color.base)
 			left, wid = get_boundaries(n)
 			if file.ext =~ /(?:rar|zip|7z|tar|gz)$/ and file.size < 10485760
 				text = `aunpack -l #{file.sh} 2>> /dev/null`
@@ -34,75 +33,89 @@ module Fm
 		column_clear(n, i)
 	end
 
-	def self.put_directory(c, d)
+	def put_directory(c, d)
 		l = 1
-		if d
-			infos = (c == COLUMNS - 2)
-			left, wid = get_boundaries(c)
-
-			if d.read? and not d.empty?
-
-				offset = get_offset(d, lines)
-				(lines - 1).times do |l|
-					lpo = l + offset
-					bg = -1
-					break if (f = d.files[lpo]) == nil
-#					log f
-
-					dir = false
-					if f.symlink?
-						bld = true
-						if f.broken_symlink?
-							clr = [1, bg]
-						else
-							clr = [6, bg]
-						end
-						dir = f.dir?
-					elsif f.dir?
-						bld = true
-						dir = true
-						clr = [4, bg]
-					elsif f.movie?
-						bld = true
-						clr = [5, bg]
-					elsif f.executable?
-						bld = true
-						clr = [2, bg]
-					else
-						bld = false
-						clr = [7, bg]
-					end
+		return column_clear(c, l) unless d
+
+		infos = (c == COLUMNS - 2)
+		left, wid = get_boundaries(c)
+		
+		if not d.read?
+			puti l, left, 'reading...'.ljust(wid+1)
+			Scheduler << d
+			return
+		elsif d.read? and d.empty?
+			puti l, left, 'empty'.ljust(wid+1)
+			return
+		end
 
-					fn = f.basename
-					if f.marked?
-						fn = "* #{fn}"
-					end
-					if infos
-						myinfo = " #{f.infostring}  "
-						str = fn[0, wid-1].ljust(wid+1)
-						if str.size > myinfo.size
-							str[-myinfo.size..-1] = myinfo
-							yes = true
-						else
-							yes = false
-						end
-						puti l+1, left, str
-						if dir and yes
-							args = l+1, left+wid-myinfo.size, myinfo.size, *clr
-							color_bold_at(*args)
-						end
-					else
-						puti l+1, left, fn[0, wid-1].ljust(wid+1)
-					end
 
-					args = l+1, left, fn.size.limit(wid-1), *clr
+		offset = get_offset(d, lines)
+		(lines - 1).times do |l|
+			lpo = l + offset
+			bg = -1
+			break if (f = d.files[lpo]) == nil
+
+			mycolor = if lpo == d.pos
+				Color.selected
+			elsif f.marked?
+				Color.marked
+			else
+				Color.normal
+			end
+
+			dir = false
+
+			clr = if f.symlink?
+				dir = f.dir?
+				if f.broken_symlink?
+					mycolor.badlink
+				else
+					mycolor.goodlink
+				end
+			elsif f.dir?
+				dir = true
+				mycolor.directory
+			elsif f.movie?
+				mycolor.video
+			elsif f.executable?
+				mycolor.executable
+			else
+				mycolor.file
+			end
+
+			fn = f.basename
+			if f.marked?
+				fn = "* #{fn}"
+			end
+
+			if infos
+				myinfo = " #{f.infostring}  "
+				str = fn[0, wid-1].ljust(wid+1)
+				if str.size > myinfo.size
+					str[-myinfo.size..-1] = myinfo
+					yes = true
+				else
+					yes = false
+				end
+				puti l+1, left, str
+				if dir and yes
+					args = l+1, left+wid-myinfo.size, myinfo.size, *clr
+#							color_bold_at(*args)
+					attr_at(l+1, left+wid-myinfo.size, myinfo.size, Color.directory)
+				end
+			else
+				puti l+1, left, fn[0, wid-1].ljust(wid+1)
+			end
+
+			args = l+1, left, fn.size.limit(wid-1), *clr
 
-					if d.pos == lpo
-						if c == COLUMNS - 2
+			if d.pos == lpo
+				if c == COLUMNS - 2
 #							puti l+1, left-1, '^'
 #							puti l+1, left+args[2], '$'
 
-							args[4] = 0
+					args[4] = 0
 #							args[1] -= 1
 #							if args[2] < 5
 #								args[2] = 7
@@ -111,44 +124,35 @@ module Fm
 #							end
 #							color_bold_at(l+1, left-1, 1, 0, 0)
 #							color_bold_at(l+1, left+args[2], 1, 0, 0)
-							color_reverse_bold_at(*args)
 
-							# ...
+#							color_reverse_bold_at(*args)
+					attr_at(args[0], args[1], args[2], Color.selected.base)
+
+					# ...
 #							args[1] -= 1; args[2] += 2
 #							color_bold_at(*args)
-							args[1] += 1; args[2] -= 2
-							color_reverse_bold_at(*args)
-						else
-							color_reverse_at(*args)
-						end
+					args[1] += 1; args[2] -= 2
+
+#							color_reverse_bold_at(*args)
+					attr_at(args[0], args[1], args[2], Color.selected.base)
+				else
+					attr_at(args[0], args[1], args[2], Color.selected.base)
+#							color_reverse_at(*args)
+				end
 #						if f.marked?
 #							args[1] += 1
 #							args[2] = 1
 #							args[3] = 1
 #							color_reverse_at(*args)
 #						end
-					else
-						if bld then color_at(*args) else color_at(*args) end
-#						if bld then color_bold_at(*args) else color_at(*args) end
-					end
-				end
-			elsif d.read? and d.empty?
-				puti l, left, 'empty'.ljust(wid+1)
-
-			elsif not d.read?
-				puti l, left, 'reading...'.ljust(wid+1)
-				Scheduler << d
 			else
-				puti l, left, 'ERROR'.ljust(wid+1)
-
+				attr_at(args[0], args[1], args[2], Color.media)
 			end
 		end
-
-		column_clear(c, l)
 	end
 
 	def self.column_clear(n, from=0)
-		color(-1,-1)
+		attr_set(Color.base)
 		left, wid = get_boundaries(n)
 		(from -1).upto(lines) do |l|
 			puti l+2, left, ' ' * (wid+1)
@@ -192,7 +196,7 @@ module Fm
 	end
 
 	def self.draw
-		bold false
+#		bold false
 		@cur_y = get_boundaries(COLUMNS-2)[0]
 
 		if @buffer =~ /^block/
@@ -252,12 +256,12 @@ module Fm
 			end
 
 			bg = -1
-			color_at 0, 0, -1, 7, bg
-			color_at 0, 0, s1.size, 7, bg
-			color_at 0, s1.size, s2.size, 6, bg
-			color_at 0, s1.size + s2.size, s3.size, 5, bg
+#			color_at 0, 0, -1, 7, bg
+#			color_at 0, 0, s1.size, 7, bg
+#			color_at 0, s1.size, s2.size, 6, bg
+#			color_at 0, s1.size + s2.size, s3.size, 5, bg
 
-			bold false
+#			bold false
 
 			begin
 				if cf.dir?
@@ -283,8 +287,9 @@ module Fm
 				end
 			end
 
-			bold false
-			color(-1, -1)
+#			bold false
+			attr_set(Color.base)
+#			color(-1, -1)
 			btm = lines - 1
 
 			case @buffer
@@ -302,9 +307,9 @@ module Fm
 				end
 				puti btm, "  #{Time.now.strftime("%H:%M:%S %a %b %d")}  #{cf.rights} #{more}"
 
-				color_at btm, 23, 10, (cf.writable? ? 6 : 5), -1
+#				color_at btm, 23, 10, (cf.writable? ? 6 : 5), -1
 				if more
-					color_at btm, 34, more.size, (cf.exists? ? 6 : 1), -1
+#					color_at btm, 34, more.size, (cf.exists? ? 6 : 1), -1
 				end
 			end
 
@@ -323,10 +328,10 @@ module Fm
 			done = bar.done
 			c = (done * cols).to_i
 			unless done == 0
-				color_at l, 0, c, 0, 4
+#				color_at l, 0, c, 0, 4
 			end
 			unless done == cols
-				color_at l, c, -1, 0, 6
+#				color_at l, c, -1, 0, 6
 			end
 		end
 	end
diff --git a/data/colorscheme/default.rb b/data/colorscheme/default.rb
new file mode 100644
index 00000000..347afb75
--- /dev/null
+++ b/data/colorscheme/default.rb
@@ -0,0 +1,11 @@
+module Color
+	@base = df, df
+	@link = cyan, df
+	@directory = blue, df
+	@media = pink, df
+	@executable = green, df
+
+	module Selected
+		@base = cyan, black, reverse
+	end
+end
diff --git a/ranger.rb b/ranger.rb
index d503dc50..9e6b4380 100755
--- a/ranger.rb
+++ b/ranger.rb
@@ -36,6 +36,7 @@ for file in Dir.glob "#{MYDIR}/code/**/*.rb"
 	require file [MYDIR.size + 1 ... -3]
 end
 
+load 'data/colorscheme/default.rb'
 require 'data/screensaver/clock.rb'
 
 unless ARGV.empty? or File.directory?(pwd)