/plugins/ProjectViewer/branches/pv_2_0_3_patches/projectviewer/vpt/IconComposer.java

# · Java · 291 lines · 188 code · 40 blank · 63 comment · 28 complexity · 91130f04e8fd920b1f1673d2e40f18d8 MD5 · raw file

  1. /*
  2. * :tabSize=4:indentSize=4:noTabs=false:
  3. * :folding=explicit:collapseFolds=1:
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License
  7. * as published by the Free Software Foundation; either version 2
  8. * of the License, or any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  18. */
  19. package projectviewer.vpt;
  20. //{{{ Imports
  21. import java.io.File;
  22. import java.util.HashMap;
  23. import java.awt.Image;
  24. import java.awt.image.ColorModel;
  25. import java.awt.image.MemoryImageSource;
  26. import java.awt.image.PixelGrabber;
  27. import java.awt.Toolkit;
  28. import javax.swing.Icon;
  29. import javax.swing.ImageIcon;
  30. import org.gjt.sp.jedit.Buffer;
  31. import org.gjt.sp.jedit.EditPlugin;
  32. import org.gjt.sp.jedit.jEdit;
  33. import org.gjt.sp.util.Log;
  34. import errorlist.ErrorSource;
  35. import projectviewer.config.ProjectViewerConfig;
  36. //}}}
  37. /**
  38. * Create decorated icons for VPT nodes
  39. *
  40. * @author Stefan Kost
  41. * @version $Id: IconComposer.java 6268 2004-07-13 21:58:34Z vanza $
  42. */
  43. public final class IconComposer {
  44. //{{{ Constants
  45. public final static int FILE_STATE_NORMAL = 0;
  46. public final static int FILE_STATE_CHANGED = 1;
  47. public final static int FILE_STATE_READONLY = 2;
  48. public final static int FILE_STATE_NOT_FOUND = 3;
  49. public final static int VC_STATE_NONE = 0;
  50. public final static int MSG_STATE_NONE = 0;
  51. public final static int MSG_STATE_MESSAGES = 1;
  52. public final static int MSG_STATE_ERRORS = 2;
  53. //}}}
  54. //{{{ Attributes
  55. private final static HashMap iconCache = new HashMap();
  56. private final static Icon FILE_STATE_CHANGED_IMG =
  57. new ImageIcon(IconComposer.class.getResource("/images/file_state_changed.png"));
  58. private final static Icon FILE_STATE_READONLY_IMG =
  59. new ImageIcon(IconComposer.class.getResource("/images/file_state_readonly.png"));
  60. private final static Icon FILE_STATE_NOT_FOUND_IMG =
  61. new ImageIcon(IconComposer.class.getResource("/images/file_state_not_found.png"));
  62. private final static Icon MSG_STATE_MESSAGES_IMG =
  63. new ImageIcon(IconComposer.class.getResource("/images/msg_state_messages.png"));
  64. private final static Icon MSG_STATE_ERRORS_IMG =
  65. new ImageIcon(IconComposer.class.getResource("/images/msg_state_errors.png"));
  66. //}}}
  67. //{{{ Public methods
  68. //{{{ +_composeIcon(File, String, Icon)_ : Icon
  69. public static Icon composeIcon(File f, String path, Icon baseIcon) {
  70. Icon[][][][] cache = getIconCache(baseIcon);
  71. int msg_state = MSG_STATE_NONE;
  72. if (ProjectViewerConfig.getInstance().isErrorListAvailable()) {
  73. msg_state = Helper.getMessageState(path);
  74. }
  75. int file_state = getFileState(f, path);
  76. int vc_state = VC_STATE_NONE;
  77. try {
  78. if(cache[vc_state][0][file_state][msg_state] == null) {
  79. Icon tl = null; // vc_state
  80. Icon tr = null; // unused
  81. Icon bl = null; // file_state
  82. switch(file_state) {
  83. case FILE_STATE_CHANGED:
  84. bl = FILE_STATE_CHANGED_IMG;
  85. break;
  86. case FILE_STATE_READONLY:
  87. bl = FILE_STATE_READONLY_IMG;
  88. break;
  89. case FILE_STATE_NOT_FOUND:
  90. bl = FILE_STATE_NOT_FOUND_IMG;
  91. break;
  92. }
  93. Icon br = null; // msg_state
  94. switch(msg_state) {
  95. case MSG_STATE_MESSAGES:
  96. br = MSG_STATE_MESSAGES_IMG;
  97. break;
  98. case MSG_STATE_ERRORS:
  99. br = MSG_STATE_ERRORS_IMG;
  100. break;
  101. }
  102. cache[vc_state][0][file_state][msg_state] =
  103. composeIcons(baseIcon, tl, tr, bl, br);
  104. }
  105. baseIcon = cache[vc_state][0][file_state][msg_state];
  106. } catch(ArrayIndexOutOfBoundsException ex) {
  107. Log.log(Log.WARNING, null, ex);
  108. }
  109. return baseIcon;
  110. } //}}}
  111. //}}}
  112. //{{{ Private methods
  113. //{{{ -_composeIcons(Icon, Icon, Icon, Icon, Icon)_ : Icon
  114. private static Icon composeIcons(Icon baseIcon, Icon tl, Icon tr, Icon bl, Icon br) {
  115. // copy base image
  116. int baseWidth = baseIcon.getIconWidth();
  117. int baseHeight = baseIcon.getIconHeight();
  118. if (tl != null) {
  119. baseIcon = composeIcons(baseIcon, tl, 0, 0);
  120. }
  121. if (tr != null) {
  122. baseIcon = composeIcons(baseIcon, tr, baseWidth - tr.getIconWidth(), 0);
  123. }
  124. if (bl != null) {
  125. baseIcon = composeIcons(baseIcon, bl, 0, baseHeight - bl.getIconHeight());
  126. }
  127. if (br != null) {
  128. baseIcon = composeIcons(baseIcon, br,
  129. baseWidth - br.getIconWidth(), baseHeight - br.getIconHeight());
  130. }
  131. return baseIcon;
  132. } //}}}
  133. //{{{ -_composeIcons(Icon, Icon, int, int)_ : Icon
  134. private static Icon composeIcons(Icon baseIcon, Icon decoIcon, int px, int py) {
  135. Image baseImage=((ImageIcon)baseIcon).getImage();
  136. int baseWidth=baseIcon.getIconWidth();
  137. int baseHeight=baseIcon.getIconHeight();
  138. int [] base = new int[baseWidth*baseHeight];
  139. PixelGrabber basePG = new PixelGrabber(baseImage, 0, 0, baseWidth, baseHeight, base, 0, baseWidth);
  140. try { basePG.grabPixels(); } catch (Exception ie1) { }
  141. Image decoImage=((ImageIcon)decoIcon).getImage();
  142. int decoWidth=decoIcon.getIconWidth();
  143. int decoHeight=decoIcon.getIconHeight();
  144. int [] deco = new int[decoWidth*decoHeight];
  145. PixelGrabber decoPG = new PixelGrabber(decoImage, 0, 0, decoWidth, decoHeight, deco, 0, decoWidth);
  146. try { decoPG.grabPixels(); } catch (Exception ie1) { }
  147. //Log.log(Log.DEBUG, null, "baseSize :["+baseWidth+"x"+baseHeight+"]");
  148. //Log.log(Log.DEBUG, null, "decoSize :["+decoWidth+"x"+decoHeight+"]");
  149. // overlay base icon with deco icon
  150. int baseIx,decoIx;
  151. int p,bb,bg,br,ba,db,dg,dr,da,r,g,b,a;
  152. double bw,dw;
  153. for(int y = 0; y < decoHeight; y++) {
  154. for(int x = 0; x < decoWidth; x++) {
  155. decoIx = y * decoWidth + x;
  156. baseIx = (py+y) * baseWidth +(px+x);
  157. // read pixels
  158. p=base[baseIx];
  159. bb = p & 0x00ff;
  160. bg = (p >> 8) & 0x00ff;
  161. br = (p >> 16) & 0x00ff;
  162. ba = (p >> 24) & 0x00ff;
  163. p=deco[decoIx];
  164. db = p & 0x00ff;
  165. dg = (p >> 8) & 0x00ff;
  166. dr = (p >> 16) & 0x00ff;
  167. da = (p >> 24) & 0x00ff;
  168. // combining the pixels
  169. /*
  170. dw = (da / 255.0);
  171. r = ((int)(br + dr * dw)) >> 1;
  172. r = (r < 0)?(0):((r>255)?(255):(r));
  173. g = ((int)(bg + dg * dw)) >> 1;
  174. g = (g < 0)?(0):((g>255)?(255):(g));
  175. b = ((int)(bb + db * dw)) >> 1;
  176. b = (b < 0)?(0):((b>255)?(255):(b));
  177. a = ((int)(ba + da * dw)) >> 1;
  178. a = (a < 0)?(0):((a>255)?(255):(a));
  179. */
  180. dw = (da / 255.0);bw = 1.0 - dw;
  181. r = (int)(br * bw + dr * dw);
  182. r = (r < 0)?(0):((r>255)?(255):(r));
  183. g = (int)(bg * bw + dg * dw);
  184. g = (g < 0)?(0):((g>255)?(255):(g));
  185. b = (int)(bb * bw + db * dw);
  186. b = (b < 0)?(0):((b>255)?(255):(b));
  187. a = (int)(ba * bw + da * dw);
  188. a = (a < 0)?(0):((a>255)?(255):(a));
  189. p = (((((a << 8) + (r & 0x0ff)) << 8) + (g & 0x0ff)) << 8) + (b & 0x0ff);
  190. // save the pixel
  191. base[baseIx] = p;
  192. }
  193. }
  194. ColorModel cm = ColorModel.getRGBdefault();
  195. MemoryImageSource mis =
  196. new MemoryImageSource(baseWidth, baseHeight, cm, base, 0, baseWidth);
  197. Image compositeImage = Toolkit.getDefaultToolkit().createImage(mis);
  198. return (new ImageIcon(compositeImage));
  199. } //}}}
  200. //{{{ -_getIconCache(Icon)_ : Icon[][][][][]
  201. private static Icon[][][][] getIconCache(Icon icon) {
  202. Icon[][][][] cache = (Icon[][][][]) iconCache.get(icon);
  203. if (cache == null) {
  204. cache = new Icon[1][1][4][3];
  205. iconCache.put(icon, cache);
  206. }
  207. return cache;
  208. } //}}}
  209. //{{{ -_getFileState(File, String)_ : int
  210. private static int getFileState(File f, String path) {
  211. if (f != null && !f.exists())
  212. return FILE_STATE_NOT_FOUND;
  213. Buffer buffer = jEdit.getBuffer(path);
  214. int file_state = IconComposer.FILE_STATE_NORMAL;
  215. if (buffer != null) {
  216. if(buffer.isDirty()) {
  217. return FILE_STATE_CHANGED;
  218. } else if (!buffer.isEditable()) {
  219. return FILE_STATE_READONLY;
  220. }
  221. }
  222. return FILE_STATE_NORMAL;
  223. } //}}}
  224. //}}}
  225. //{{{ -class _Helper_
  226. /**
  227. * Class to hold references to classes that may not be available, so this
  228. * class can behave well when called from a BeanShell script.
  229. */
  230. private static class Helper {
  231. //{{{ +_getMessageState(String)_ : int
  232. public static int getMessageState(String path) {
  233. int msg_state = IconComposer.MSG_STATE_NONE;
  234. ErrorSource[] sources = ErrorSource.getErrorSources();
  235. for(int i = 0; i < sources.length; i++) {
  236. if (sources[i].getFileErrorCount(path) > 0) {
  237. msg_state = IconComposer.MSG_STATE_MESSAGES;
  238. ErrorSource.Error[] errors = sources[i].getAllErrors();
  239. for(int j=0; j < errors.length; j++) {
  240. if(errors[j].getErrorType() == ErrorSource.ERROR) {
  241. msg_state = IconComposer.MSG_STATE_ERRORS;
  242. break;
  243. }
  244. }
  245. break;
  246. }
  247. }
  248. return msg_state;
  249. } //}}}
  250. } //}}}
  251. }