PageRenderTime 36ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/bundles/plugins-trunk/BufferTabs/buffertabs/ColorTabs.java

#
Java | 401 lines | 246 code | 58 blank | 97 comment | 20 complexity | 0cfdfff28cf2fcd7eda210e65e22a200 MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-1.0, Apache-2.0, LGPL-2.0, LGPL-3.0, GPL-2.0, CC-BY-SA-3.0, LGPL-2.1, GPL-3.0, MPL-2.0-no-copyleft-exception, IPL-1.0
  1. /*
  2. * ColorTabs.java - Part of the BufferTabs plugin for jEdit.
  3. * Copyright (C) 2003 Chris Samuels
  4. * :tabSize=8:indentSize=8:noTabs=false:
  5. * :folding=explicit:collapseFolds=1:
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version 2
  10. * of the License, or any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  20. */
  21. package buffertabs;
  22. //{{{ Imports
  23. import java.awt.Color;
  24. import java.util.Map;
  25. import java.util.HashMap;
  26. import java.util.Random;
  27. import java.util.List;
  28. import java.util.ArrayList;
  29. import java.util.regex.Pattern;
  30. import java.util.regex.PatternSyntaxException;
  31. import org.gjt.sp.jedit.jEdit;
  32. import org.gjt.sp.util.Log;
  33. import org.gjt.sp.util.StandardUtilities;
  34. //}}}
  35. /**
  36. * An add-on to BufferTabs to allow colored backgrounds on tabs
  37. *
  38. * @author Chris Samuels
  39. * @created 24 February 2003
  40. */
  41. public class ColorTabs
  42. {
  43. private static final int JND = 4;
  44. private static final int DARKEN_LOWEST_COLOR = 0;
  45. private static final int DARKEN_HIGHEST_COLOR = 150;
  46. private static final int DARKEN_RANGE = DARKEN_HIGHEST_COLOR - DARKEN_LOWEST_COLOR;
  47. private static final float DARKEN_RATIO = ((float) DARKEN_RANGE / 254);
  48. private static final int MUTE_LOWEST_COLOR = 150;
  49. private static final int MUTE_HIGHEST_COLOR = 230;
  50. private static final int MUTE_RANGE = MUTE_HIGHEST_COLOR - MUTE_LOWEST_COLOR;
  51. private static final float MUTE_RATIO = ((float) MUTE_RANGE / 254);
  52. private static ColorTabs colorTabs = null;
  53. private boolean enabled = false;
  54. private boolean selectedColorized = true;
  55. private boolean selectedForegroundColorized = false;
  56. private boolean foregroundColorized = false;
  57. private boolean muteColors = true;
  58. private boolean colorVariation = true;
  59. private List<ColorEntry> colors;
  60. private final Map<String,Color> colorsAssigned = new HashMap<String,Color>();
  61. private final Object lock = new Object();
  62. private Random rnd = null;
  63. //{{{ ColorTabs constructor
  64. /**
  65. * Singleton class
  66. */
  67. private ColorTabs() { }
  68. //}}}
  69. //{{{ isEnabled() method
  70. public boolean isEnabled()
  71. {
  72. return this.enabled;
  73. } //}}}
  74. //{{{ setEnabled() method
  75. public void setEnabled(boolean enabled)
  76. {
  77. this.enabled = enabled;
  78. } //}}}
  79. //{{{ isSelectedColorized() method
  80. public boolean isSelectedColorized()
  81. {
  82. return this.selectedColorized;
  83. } //}}}
  84. //{{{ setSelectedColorized() method
  85. public void setSelectedColorized(boolean selectedColorized)
  86. {
  87. this.selectedColorized = selectedColorized;
  88. } //}}}
  89. //{{{ isForegroundColorized() method
  90. public boolean isForegroundColorized()
  91. {
  92. return this.foregroundColorized;
  93. } //}}}
  94. //{{{ isSelectedForegroundColorized() method
  95. public boolean isSelectedForegroundColorized()
  96. {
  97. return this.selectedForegroundColorized;
  98. } //}}}
  99. //{{{ setForegroundColorized() method
  100. public void setForegroundColorized(boolean foregroundColorized)
  101. {
  102. this.foregroundColorized = foregroundColorized;
  103. } //}}}
  104. //{{{ setSelectedForegroundColorized() method
  105. public void setSelectedForegroundColorized(boolean foregroundColorized)
  106. {
  107. this.selectedForegroundColorized = foregroundColorized;
  108. } //}}}
  109. //{{{ hasMuteColors() method
  110. public boolean hasMuteColors()
  111. {
  112. return this.muteColors;
  113. } //}}}
  114. //{{{ setMuteColors() method
  115. public void setMuteColors(boolean muteColors)
  116. {
  117. this.muteColors = muteColors;
  118. } //}}}
  119. //{{{ hasColorVariation() method
  120. public boolean hasColorVariation()
  121. {
  122. return this.colorVariation;
  123. } //}}}
  124. //{{{ setColorVariation() method
  125. public void setColorVariation(boolean colorVariation)
  126. {
  127. this.colorVariation = colorVariation;
  128. } //}}}
  129. //{{{ alterColorDarken() method
  130. /**
  131. * Creates colors suitable for reading text labels. Uniformly moves the
  132. * color range to a darker range.
  133. *
  134. * @param color
  135. * @return
  136. */
  137. Color alterColorDarken(Color color)
  138. {
  139. if (color == null)
  140. {
  141. return Color.black;
  142. }
  143. int r = color.getRed();
  144. int g = color.getGreen();
  145. int b = color.getBlue();
  146. r = (int) (DARKEN_HIGHEST_COLOR - (r * DARKEN_RATIO));
  147. g = (int) (DARKEN_HIGHEST_COLOR - (g * DARKEN_RATIO));
  148. b = (int) (DARKEN_HIGHEST_COLOR - (b * DARKEN_RATIO));
  149. if (this.hasColorVariation())
  150. {
  151. r -= rnd.nextInt(5) * JND;
  152. g -= rnd.nextInt(5) * JND;
  153. b -= rnd.nextInt(5) * JND;
  154. r = r / JND * JND;
  155. g = g / JND * JND;
  156. b = b / JND * JND;
  157. }
  158. r = Math.max(DARKEN_LOWEST_COLOR, Math.min(r, DARKEN_HIGHEST_COLOR));
  159. g = Math.max(DARKEN_LOWEST_COLOR, Math.min(g, DARKEN_HIGHEST_COLOR));
  160. b = Math.max(DARKEN_LOWEST_COLOR, Math.min(b, DARKEN_HIGHEST_COLOR));
  161. return new Color(r, g, b);
  162. } //}}}
  163. //{{{ alterColorHighlight() method
  164. /**
  165. * Creates colors suitable for highlighting an active tab. Boosts the
  166. * brightness and lowers saturation to achieve this.
  167. *
  168. * @param color
  169. * @return
  170. */
  171. Color alterColorHighlight(Color color)
  172. {
  173. if (color == null)
  174. {
  175. return Color.lightGray;
  176. }
  177. int r = color.getRed();
  178. int g = color.getGreen();
  179. int b = color.getBlue();
  180. float[] hsb = Color.RGBtoHSB(r, g, b, null);
  181. float s = hsb[1];
  182. float v = hsb[2];
  183. s *= 0.6;
  184. s = Math.max(0.0f, Math.min(s, 1f));
  185. v *= 1.6;
  186. v = Math.max(0.0f, Math.min(v, 0.8f));
  187. return Color.getHSBColor(hsb[0], s, v);
  188. } //}}}
  189. //{{{ alterColorMute() method
  190. /**
  191. * Creates colors suitable for backgrounds. Uniformly moves the color
  192. * range to a lighter paler range.
  193. *
  194. *@param color
  195. *@return
  196. */
  197. Color alterColorMute(Color color)
  198. {
  199. if (color == null)
  200. {
  201. return Color.gray;
  202. }
  203. int r = color.getRed();
  204. int g = color.getGreen();
  205. int b = color.getBlue();
  206. r = (int) (MUTE_LOWEST_COLOR + (r * MUTE_RATIO));
  207. g = (int) (MUTE_LOWEST_COLOR + (g * MUTE_RATIO));
  208. b = (int) (MUTE_LOWEST_COLOR + (b * MUTE_RATIO));
  209. if (this.hasColorVariation())
  210. {
  211. r += rnd.nextInt(5) * JND;
  212. g += rnd.nextInt(5) * JND;
  213. b += rnd.nextInt(5) * JND;
  214. r = r / JND * JND;
  215. g = g / JND * JND;
  216. b = b / JND * JND;
  217. }
  218. r = Math.max(MUTE_LOWEST_COLOR, Math.min(r, MUTE_HIGHEST_COLOR));
  219. g = Math.max(MUTE_LOWEST_COLOR, Math.min(g, MUTE_HIGHEST_COLOR));
  220. b = Math.max(MUTE_LOWEST_COLOR, Math.min(b, MUTE_HIGHEST_COLOR));
  221. return new Color(r, g, b);
  222. } //}}}
  223. //{{{ getDefaultColorFor() method
  224. /**
  225. * Gets the defaultColorFor attribute of the ColorTabs class
  226. *
  227. * @param name
  228. * @return The defaultColorFor value
  229. */
  230. public Color getDefaultColorFor(String name)
  231. {
  232. synchronized (lock)
  233. {
  234. if (colors == null)
  235. {
  236. loadColors();
  237. }
  238. if (colorsAssigned.containsKey(name))
  239. {
  240. return colorsAssigned.get(name);
  241. }
  242. for (int i = 0; i < colors.size(); i++)
  243. {
  244. ColorEntry entry = colors.get(i);
  245. if (entry.re.matcher(name).matches())
  246. {
  247. Color newColor = null;
  248. if (this.hasMuteColors())
  249. {
  250. if (this.isForegroundColorized())
  251. {
  252. newColor = alterColorDarken(entry.color);
  253. }
  254. else
  255. {
  256. newColor = alterColorMute(entry.color);
  257. }
  258. }
  259. else
  260. {
  261. newColor = entry.color;
  262. }
  263. colorsAssigned.put(name, newColor);
  264. return newColor;
  265. }
  266. }
  267. return null;
  268. }
  269. } //}}}
  270. //{{{ instance() method
  271. /**
  272. * Returns access to the Singleton ColorTabs class
  273. *
  274. * @return Singleton ColorTabs
  275. */
  276. public static ColorTabs instance()
  277. {
  278. if (colorTabs == null)
  279. {
  280. colorTabs = new ColorTabs();
  281. }
  282. return colorTabs;
  283. } //}}}
  284. //{{{ loadColors() method
  285. /**
  286. * Load the colors from 'File system browser' color options
  287. */
  288. private void loadColors()
  289. {
  290. synchronized (lock)
  291. {
  292. colors = new ArrayList<ColorEntry>();
  293. if (!jEdit.getBooleanProperty("vfs.browser.colorize"))
  294. {
  295. return;
  296. }
  297. String glob;
  298. int i = 0;
  299. while ((glob = jEdit.getProperty("vfs.browser.colors." + i + ".glob")) != null)
  300. {
  301. try
  302. {
  303. colors.add(new ColorEntry(
  304. Pattern.compile(StandardUtilities.globToRE(glob)),
  305. jEdit.getColorProperty("vfs.browser.colors." + i + ".color",
  306. Color.black)));
  307. i++;
  308. }
  309. catch (PatternSyntaxException e)
  310. {
  311. Log.log(Log.ERROR, ColorTabs.class, "Invalid regular expression: " + glob);
  312. //Log.log( Log.ERROR, ColorTabs.class, e );
  313. //Log.flushStream();
  314. }
  315. }
  316. }
  317. } //}}}
  318. //{{{ propertiesChanged() method
  319. public void propertiesChanged()
  320. {
  321. loadColors();
  322. colorsAssigned.clear();
  323. //Set seed so color variation are 'mostly' consistent during a session
  324. rnd = new java.util.Random(20020212);
  325. } //}}}
  326. //{{{ ColorEntry class
  327. /**
  328. * Class to store color match data
  329. *
  330. * @author Chris Samuels
  331. * @created 24 February 2003
  332. */
  333. static class ColorEntry
  334. {
  335. Color color;
  336. Pattern re;
  337. ColorEntry(Pattern re, Color color)
  338. {
  339. this.re = re;
  340. this.color = color;
  341. }
  342. } //}}}
  343. }