/branches/RXVT/src/scrollbar.c

# · C · 323 lines · 239 code · 35 blank · 49 comment · 22 complexity · 08c244c95423ca8be3ee88ebcd7cac13 MD5 · raw file

  1. /*--------------------------------*-C-*---------------------------------*
  2. * File: scrollbar.c
  3. *----------------------------------------------------------------------*
  4. * Copyright (C) 1997 1998 mj olesen <olesen@me.QueensU.CA>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19. *
  20. *----------------------------------------------------------------------*/
  21. #include "rxvt.h" /* NECESSARY */
  22. /*----------------------------------------------------------------------*
  23. */
  24. static GC scrollbarGC;
  25. #ifdef XTERM_SCROLLBAR /* bitmap scrollbar */
  26. static GC ShadowGC;
  27. static char sb_bits[] =
  28. {0xaa, 0x0a, 0x55, 0x05}; /* 12x2 bitmap */
  29. #if (SB_WIDTH != 15)
  30. Error, check scrollbar width (SB_WIDTH). It must be 15 for XTERM_SCROLLBAR
  31. #endif
  32. #else /* XTERM_SCROLLBAR */
  33. static GC topShadowGC, botShadowGC;
  34. /* draw triangular up button with a shadow of SHADOW (1 or 2) pixels */
  35. /* PROTO */
  36. void
  37. Draw_up_button(int x, int y, int state)
  38. {
  39. const unsigned int sz = (SB_WIDTH), sz2 = (SB_WIDTH / 2);
  40. XPoint pt[3];
  41. GC top, bot;
  42. switch (state) {
  43. case +1:
  44. top = topShadowGC;
  45. bot = botShadowGC;
  46. break;
  47. case -1:
  48. top = botShadowGC;
  49. bot = topShadowGC;
  50. break;
  51. default:
  52. top = bot = scrollbarGC;
  53. break;
  54. }
  55. /* fill triangle */
  56. pt[0].x = x;
  57. pt[0].y = y + sz - 1;
  58. pt[1].x = x + sz - 1;
  59. pt[1].y = y + sz - 1;
  60. pt[2].x = x + sz2;
  61. pt[2].y = y;
  62. XFillPolygon(Xdisplay, scrollBar.win, scrollbarGC,
  63. pt, 3, Convex, CoordModeOrigin);
  64. /* draw base */
  65. XDrawLine(Xdisplay, scrollBar.win, bot,
  66. pt[0].x, pt[0].y, pt[1].x, pt[1].y);
  67. /* draw shadow */
  68. pt[1].x = x + sz2 - 1;
  69. pt[1].y = y;
  70. XDrawLine(Xdisplay, scrollBar.win, top,
  71. pt[0].x, pt[0].y, pt[1].x, pt[1].y);
  72. #if (SHADOW > 1)
  73. /* doubled */
  74. pt[0].x++;
  75. pt[0].y--;
  76. pt[1].y++;
  77. XDrawLine(Xdisplay, scrollBar.win, top,
  78. pt[0].x, pt[0].y, pt[1].x, pt[1].y);
  79. #endif
  80. /* draw shadow */
  81. pt[0].x = x + sz2;
  82. pt[0].y = y;
  83. pt[1].x = x + sz - 1;
  84. pt[1].y = y + sz - 1;
  85. XDrawLine(Xdisplay, scrollBar.win, bot,
  86. pt[0].x, pt[0].y, pt[1].x, pt[1].y);
  87. #if (SHADOW > 1)
  88. /* doubled */
  89. pt[0].y++;
  90. pt[1].x--;
  91. pt[1].y--;
  92. XDrawLine(Xdisplay, scrollBar.win, bot,
  93. pt[0].x, pt[0].y, pt[1].x, pt[1].y);
  94. #endif
  95. }
  96. /* draw triangular down button with a shadow of SHADOW (1 or 2) pixels */
  97. /* PROTO */
  98. void
  99. Draw_dn_button(int x, int y, int state)
  100. {
  101. const unsigned int sz = (SB_WIDTH), sz2 = (SB_WIDTH / 2);
  102. XPoint pt[3];
  103. GC top, bot;
  104. switch (state) {
  105. case +1:
  106. top = topShadowGC;
  107. bot = botShadowGC;
  108. break;
  109. case -1:
  110. top = botShadowGC;
  111. bot = topShadowGC;
  112. break;
  113. default:
  114. top = bot = scrollbarGC;
  115. break;
  116. }
  117. /* fill triangle */
  118. pt[0].x = x;
  119. pt[0].y = y;
  120. pt[1].x = x + sz - 1;
  121. pt[1].y = y;
  122. pt[2].x = x + sz2;
  123. pt[2].y = y + sz;
  124. XFillPolygon(Xdisplay, scrollBar.win, scrollbarGC,
  125. pt, 3, Convex, CoordModeOrigin);
  126. /* draw base */
  127. XDrawLine(Xdisplay, scrollBar.win, top,
  128. pt[0].x, pt[0].y, pt[1].x, pt[1].y);
  129. /* draw shadow */
  130. pt[1].x = x + sz2 - 1;
  131. pt[1].y = y + sz - 1;
  132. XDrawLine(Xdisplay, scrollBar.win, top,
  133. pt[0].x, pt[0].y, pt[1].x, pt[1].y);
  134. #if (SHADOW > 1)
  135. /* doubled */
  136. pt[0].x++;
  137. pt[0].y++;
  138. pt[1].y--;
  139. XDrawLine(Xdisplay, scrollBar.win, top,
  140. pt[0].x, pt[0].y, pt[1].x, pt[1].y);
  141. #endif
  142. /* draw shadow */
  143. pt[0].x = x + sz2;
  144. pt[0].y = y + sz - 1;
  145. pt[1].x = x + sz - 1;
  146. pt[1].y = y;
  147. XDrawLine(Xdisplay, scrollBar.win, bot,
  148. pt[0].x, pt[0].y, pt[1].x, pt[1].y);
  149. #if (SHADOW > 1)
  150. /* doubled */
  151. pt[0].y--;
  152. pt[1].x--;
  153. pt[1].y++;
  154. XDrawLine(Xdisplay, scrollBar.win, bot,
  155. pt[0].x, pt[0].y, pt[1].x, pt[1].y);
  156. #endif
  157. }
  158. #endif /* XTERM_SCROLLBAR */
  159. /* PROTO */
  160. int
  161. scrollbar_mapping(int map)
  162. {
  163. int change = 0;
  164. if (map && !scrollbar_visible()) {
  165. scrollBar.state = 1;
  166. XMapWindow(Xdisplay, scrollBar.win);
  167. change = 1;
  168. } else if (!map && scrollbar_visible()) {
  169. scrollBar.state = 0;
  170. XUnmapWindow(Xdisplay, scrollBar.win);
  171. change = 1;
  172. }
  173. return change;
  174. }
  175. /* PROTO */
  176. int
  177. scrollbar_show(int update)
  178. {
  179. static short last_top, last_bot, sb_width; /* old (drawn) values */
  180. int xsb = 0;
  181. if (!scrollbar_visible())
  182. return 0;
  183. if (scrollbarGC == None) {
  184. XGCValues gcvalue;
  185. #ifdef XTERM_SCROLLBAR
  186. sb_width = SB_WIDTH - 1;
  187. gcvalue.stipple = XCreateBitmapFromData(Xdisplay, scrollBar.win,
  188. sb_bits, 12, 2);
  189. if (!gcvalue.stipple) {
  190. print_error("can't create bitmap");
  191. exit(EXIT_FAILURE);
  192. }
  193. gcvalue.fill_style = FillOpaqueStippled;
  194. gcvalue.foreground = PixColors[fgColor];
  195. gcvalue.background = PixColors[bgColor];
  196. scrollbarGC = XCreateGC(Xdisplay, scrollBar.win,
  197. GCForeground | GCBackground |
  198. GCFillStyle | GCStipple,
  199. &gcvalue);
  200. gcvalue.foreground = PixColors[borderColor];
  201. ShadowGC = XCreateGC(Xdisplay, scrollBar.win, GCForeground, &gcvalue);
  202. #else /* XTERM_SCROLLBAR */
  203. sb_width = SB_WIDTH;
  204. gcvalue.foreground = (Xdepth <= 2 ? PixColors[fgColor]
  205. : PixColors[scrollColor]);
  206. scrollbarGC = XCreateGC(Xdisplay, scrollBar.win, GCForeground,
  207. &gcvalue);
  208. if (sb_shadow) {
  209. XSetWindowBackground(Xdisplay, scrollBar.win, gcvalue.foreground);
  210. XClearWindow(Xdisplay, scrollBar.win);
  211. }
  212. gcvalue.foreground = PixColors[topShadowColor];
  213. topShadowGC = XCreateGC(Xdisplay, scrollBar.win,
  214. GCForeground,
  215. &gcvalue);
  216. gcvalue.foreground = PixColors[bottomShadowColor];
  217. botShadowGC = XCreateGC(Xdisplay, scrollBar.win,
  218. GCForeground,
  219. &gcvalue);
  220. #endif /* XTERM_SCROLLBAR */
  221. }
  222. if (update) {
  223. int top = (TermWin.nscrolled - TermWin.view_start);
  224. int bot = top + (TermWin.nrow - 1);
  225. int len = max((TermWin.nscrolled + (TermWin.nrow - 1)),1);
  226. scrollBar.top = (scrollBar.beg + (top * scrollbar_size()) / len);
  227. scrollBar.bot = (scrollBar.beg + (bot * scrollbar_size()) / len);
  228. /* no change */
  229. if ((scrollBar.top == last_top) && (scrollBar.bot == last_bot))
  230. return 0;
  231. }
  232. /* instead of XClearWindow (Xdisplay, scrollBar.win); */
  233. #ifdef XTERM_SCROLLBAR
  234. xsb = (Options & Opt_scrollBar_right) ? 1 : 0;
  235. #endif
  236. if (last_top < scrollBar.top)
  237. XClearArea(Xdisplay, scrollBar.win,
  238. sb_shadow + xsb, last_top,
  239. sb_width, (scrollBar.top - last_top),
  240. False);
  241. if (scrollBar.bot < last_bot)
  242. XClearArea(Xdisplay, scrollBar.win,
  243. sb_shadow + xsb, scrollBar.bot,
  244. sb_width, (last_bot - scrollBar.bot),
  245. False);
  246. last_top = scrollBar.top;
  247. last_bot = scrollBar.bot;
  248. /* scrollbar slider */
  249. #ifdef XTERM_SCROLLBAR
  250. XFillRectangle(Xdisplay, scrollBar.win, scrollbarGC,
  251. xsb + 1, scrollBar.top,
  252. sb_width - 2, (scrollBar.bot - scrollBar.top));
  253. XDrawLine(Xdisplay, scrollBar.win, ShadowGC,
  254. xsb ? 0 : 14, scrollBar.beg, xsb ? 0 : 14, scrollBar.end);
  255. #else
  256. #ifdef SB_BORDER
  257. XDrawLine(Xdisplay, scrollBar.win, botShadowGC,
  258. SB_WIDTH, 0, SB_WIDTH, scrollBar.end + SB_WIDTH) ;
  259. #endif
  260. XFillRectangle(Xdisplay, scrollBar.win, scrollbarGC,
  261. sb_shadow, scrollBar.top,
  262. sb_width, (scrollBar.bot - scrollBar.top));
  263. if (sb_shadow)
  264. /* trough shadow */
  265. Draw_Shadow(scrollBar.win,
  266. botShadowGC, topShadowGC,
  267. 0, 0,
  268. (sb_width + 2 * sb_shadow),
  269. (scrollBar.end + (sb_width + 1) + sb_shadow));
  270. /* shadow for scrollbar slider */
  271. Draw_Shadow(scrollBar.win,
  272. topShadowGC, botShadowGC,
  273. sb_shadow, scrollBar.top, sb_width,
  274. (scrollBar.bot - scrollBar.top));
  275. /*
  276. * Redraw scrollbar arrows
  277. */
  278. #ifdef NEXT_SCROLLBAR
  279. Draw_up_button(sb_shadow, (scrollBar.end + 1), (scrollbar_isUp()? -1 : +1));
  280. Draw_dn_button(sb_shadow, (scrollBar.end + SB_WIDTH + 2), (scrollbar_isDn()? -1 : +1));
  281. #else
  282. Draw_up_button(sb_shadow, sb_shadow, (scrollbar_isUp()? -1 : +1));
  283. Draw_dn_button(sb_shadow, (scrollBar.end + 1), (scrollbar_isDn()? -1 : +1));
  284. #endif
  285. #endif /* XTERM_SCROLLBAR */
  286. return 1;
  287. }
  288. /*----------------------- end-of-file (C source) -----------------------*/