PageRenderTime 25ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/dx-4.4.4/src/uipp/base/NotebookTab.C

#
C | 380 lines | 295 code | 43 blank | 42 comment | 48 complexity | 3f4fcc238152200329ff27acb0e5bf57 MD5 | raw file
Possible License(s): Unlicense, IPL-1.0
  1. /***********************************************************************/
  2. /* Open Visualization Data Explorer */
  3. /* (C) Copyright IBM Corp. 1989,1999 */
  4. /* ALL RIGHTS RESERVED */
  5. /* This code licensed under the */
  6. /* "IBM PUBLIC LICENSE - Open Visualization Data Explorer" */
  7. /***********************************************************************/
  8. #include "NotebookTab.h"
  9. #include <Xm/DrawnB.h>
  10. #include "DXStrings.h"
  11. #include "Application.h"
  12. #include <X11/Xlib.h>
  13. int NotebookTab::CornerSize = 6;
  14. boolean NotebookTab::ClassInitialized = FALSE;
  15. XmFontList NotebookTab::FontList = 0;
  16. XPoint NotebookTab::LeftCorner[] = {
  17. { 0, 5 },
  18. { 1, 5 },
  19. { 1, 4 },
  20. { 1, 3 },
  21. { 2, 3 },
  22. { 2, 2 },
  23. { 3, 2 },
  24. { 3, 1 },
  25. { 4, 1 },
  26. { 5, 0 },
  27. };
  28. //
  29. // CoordModePrevious. The user of these points must assign a valid
  30. // coordinate to the x coord of the 0th element. The x coord should be
  31. // replaced with (width-CornerSize)
  32. //
  33. XPoint NotebookTab::TopCorner[] = {
  34. { 0, 1 },
  35. { 1, 0 },
  36. { 1, 1 },
  37. };
  38. //
  39. // CoordModePrevious. The user of these points must assign a valid
  40. // coordinate to the x coord of the 0th element. The x coord should
  41. // be replaced with (width+3-CornerSize)
  42. //
  43. XPoint NotebookTab::RightCorner[] = {
  44. { 3, 3 },
  45. { 1, 1 },
  46. { 0, 1 },
  47. };
  48. NotebookTab::NotebookTab(const char* name) : UIComponent("notebookTab")
  49. {
  50. if (!NotebookTab::ClassInitialized) {
  51. NotebookTab::ClassInitialized = TRUE;
  52. }
  53. this->set = FALSE;
  54. this->label = XmStringCreateLtoR((char*)name, "small_bold");
  55. this->label_str = DuplicateString(name);
  56. this->dirty = TRUE;
  57. this->dbl_buffer = 0;
  58. this->armed = FALSE;
  59. this->multiclick_timer = 0;
  60. this->repaint_timer = 0;
  61. }
  62. NotebookTab::~NotebookTab()
  63. {
  64. if (this->multiclick_timer) XtRemoveTimeOut(this->multiclick_timer);
  65. if (this->repaint_timer) XtRemoveTimeOut(this->repaint_timer);
  66. if (this->label) XmStringFree(this->label);
  67. if (this->label_str) delete this->label_str;
  68. if (this->dbl_buffer) {
  69. XFreePixmap(XtDisplay(this->getRootWidget()), this->dbl_buffer);
  70. }
  71. Widget w = this->getRootWidget();
  72. if (w) {
  73. XtRemoveCallback (w, XmNexposeCallback, (XtCallbackProc)
  74. NotebookTab_ExposeCB, (XtPointer)this);
  75. }
  76. }
  77. void NotebookTab::createButton(Widget parent)
  78. {
  79. Widget w = XtVaCreateWidget (this->label_str, xmDrawnButtonWidgetClass, parent,
  80. XmNmultiClick, XmMULTICLICK_KEEP,
  81. XmNpushButtonEnabled, FALSE,
  82. XmNshadowThickness, 0,
  83. XmNrecomputeSize, FALSE,
  84. NULL);
  85. this->setRootWidget(w);
  86. XtAddCallback (w, XmNexposeCallback, (XtCallbackProc)
  87. NotebookTab_ExposeCB, (XtPointer)this);
  88. XtAddCallback (w, XmNarmCallback, (XtCallbackProc)
  89. NotebookTab_ArmCB, (XtPointer)this);
  90. XtAddCallback (w, XmNdisarmCallback, (XtCallbackProc)
  91. NotebookTab_DisarmCB, (XtPointer)this);
  92. XtAddCallback (w, XmNactivateCallback, (XtCallbackProc)
  93. NotebookTab_ActivateCB, (XtPointer)this);
  94. //
  95. // Use an event handler for double clicks because we want to
  96. // prevent the multiclick from causing a button-pull-out
  97. //
  98. XtAddEventHandler (w, ButtonPressMask|ButtonReleaseMask,
  99. False, (XtEventHandler)NotebookTab_ButtonEH, (XtPointer)this);
  100. }
  101. void NotebookTab::activate()
  102. {
  103. this->armed = FALSE;
  104. this->setState(this->getState()==FALSE);
  105. }
  106. void NotebookTab::arm()
  107. {
  108. this->armed = TRUE;
  109. this->setDirty(TRUE,FALSE);
  110. }
  111. void NotebookTab::disarm()
  112. {
  113. this->armed = FALSE;
  114. this->setDirty(TRUE,FALSE);
  115. }
  116. void NotebookTab::expose()
  117. {
  118. if (!XtIsRealized(this->getRootWidget())) return ;
  119. if (this->isDirty()) this->repaint();
  120. if (this->repaint_timer) {
  121. XtRemoveTimeOut(this->repaint_timer);
  122. this->repaint_timer = 0;
  123. }
  124. Dimension width,height;
  125. Widget w = this->getRootWidget();
  126. XtVaGetValues (w, XmNwidth, &width, XmNheight, &height, NULL);
  127. Window win = XtWindow(w);
  128. Display* d = XtDisplay(w);
  129. XGCValues values;
  130. GC gc = XtGetGC (w, 0, &values);
  131. XCopyArea (d, this->dbl_buffer, win, gc, 0, 0, width, height, 0, 0);
  132. }
  133. void NotebookTab::setLabel(const char* str)
  134. {
  135. if (this->label_str) delete this->label_str;
  136. if (str) this->label_str = DuplicateString(str);
  137. else this->label_str = 0;
  138. if (this->label) XmStringFree(this->label);
  139. if (str) {
  140. this->label = XmStringCreateLtoR((char*)str, (char*)this->getFont());
  141. } else {
  142. this->label = 0;
  143. }
  144. this->setDirty(TRUE,TRUE);
  145. }
  146. void NotebookTab::setState(boolean s)
  147. {
  148. if (s == this->set) return ;
  149. this->set = s;
  150. this->setDirty(TRUE, TRUE);
  151. }
  152. void NotebookTab::setDirty(boolean d, boolean repaint)
  153. {
  154. this->dirty = d;
  155. if (this->repaint_timer) XtRemoveTimeOut(this->repaint_timer);
  156. if (repaint) {
  157. this->expose();
  158. this->repaint_timer = 0;
  159. } else {
  160. XtAppContext apcxt = theApplication->getApplicationContext();
  161. int millis = 100;
  162. this->repaint_timer = XtAppAddTimeOut(apcxt, millis, (XtTimerCallbackProc)
  163. NotebookTab_RepaintTO, (XtPointer)this);
  164. }
  165. }
  166. void NotebookTab::repaint()
  167. {
  168. Widget w = this->getRootWidget();
  169. Window win = XtWindow(w);
  170. if (!win) return ;
  171. Pixel fg,ts,bs,bg;
  172. int depth;
  173. Dimension width,height;
  174. XtVaGetValues (w,
  175. XmNwidth, &width,
  176. XmNheight, &height,
  177. XmNtopShadowColor, &ts,
  178. XmNbottomShadowColor, &bs,
  179. XmNforeground, &fg,
  180. XmNbackground, &bg,
  181. XmNdepth, &depth,
  182. NULL);
  183. int s = NotebookTab::CornerSize;
  184. Display* d = XtDisplay(w);
  185. if (!this->dbl_buffer) {
  186. this->dbl_buffer = XCreatePixmap(d, win, width, height, depth);
  187. }
  188. XGCValues values;
  189. values.foreground = bg;
  190. GC gc = XtGetGC (w, GCForeground, &values);
  191. XFillRectangle (d, this->dbl_buffer, gc, 0,0,width, height);
  192. XtReleaseGC(w,gc);
  193. //
  194. // Draw left edge
  195. //
  196. boolean pushed_in =
  197. ((this->getState()) && (!this->isArmed()) ||
  198. (!this->getState()) && (this->isArmed()));
  199. if (pushed_in) {
  200. values.foreground = bs;
  201. values.background = bg;
  202. } else {
  203. values.foreground = ts;
  204. values.background = bg;
  205. }
  206. gc = XtGetGC (w, GCForeground|GCBackground, &values);
  207. XDrawLine (d, this->dbl_buffer, gc, 0,s,0,height-1);
  208. //
  209. // Draw top edge
  210. //
  211. XDrawLine (d, this->dbl_buffer, gc, s,0,width-(s+1),0);
  212. XtReleaseGC (w, gc);
  213. //
  214. // Draw right edge
  215. //
  216. if (pushed_in) {
  217. values.foreground = ts;
  218. values.background = bg;
  219. } else {
  220. values.foreground = bs;
  221. values.background = bg;
  222. }
  223. gc = XtGetGC (w, GCForeground|GCBackground, &values);
  224. XDrawLine (d, this->dbl_buffer, gc, width-1,s,width-1,height-1);
  225. XtReleaseGC(w, gc);
  226. //
  227. // Draw top left corner
  228. //
  229. if (pushed_in) {
  230. values.foreground = bs;
  231. } else {
  232. values.foreground = ts;
  233. }
  234. gc = XtGetGC (w, GCForeground, &values);
  235. int n = sizeof(NotebookTab::LeftCorner) / sizeof(XPoint);
  236. XDrawPoints (d, this->dbl_buffer, gc, NotebookTab::LeftCorner, n, CoordModeOrigin);
  237. //
  238. // Draw top portion of right corner
  239. //
  240. n = sizeof(NotebookTab::TopCorner) / sizeof(XPoint);
  241. NotebookTab::TopCorner[0].x = width - NotebookTab::CornerSize;
  242. XDrawPoints (d, this->dbl_buffer, gc, NotebookTab::TopCorner, n, CoordModePrevious);
  243. XtReleaseGC(w, gc);
  244. //
  245. // Draw bottom portion of right corner
  246. //
  247. if (pushed_in) {
  248. values.foreground = ts;
  249. } else {
  250. values.foreground = bs;
  251. }
  252. gc = XtGetGC (w, GCForeground, &values);
  253. n = sizeof(NotebookTab::RightCorner) / sizeof(XPoint);
  254. NotebookTab::RightCorner[0].x = width + 3 - NotebookTab::CornerSize;
  255. XDrawPoints (d, this->dbl_buffer, gc, NotebookTab::RightCorner, n, CoordModePrevious);
  256. XtReleaseGC(w, gc);
  257. //
  258. // Draw string
  259. //
  260. if (!NotebookTab::FontList) {
  261. XmFontList fontList;
  262. XtVaGetValues (w, XmNfontList, &fontList, NULL);
  263. NotebookTab::FontList = XmFontListCopy(fontList);
  264. }
  265. values.foreground = fg;
  266. values.background = bg;
  267. gc = XtGetGC (w, GCForeground|GCBackground, &values);
  268. Dimension strw, strh;
  269. XmStringExtent (NotebookTab::FontList, this->label, &strw, &strh);
  270. int sx = (width>>1) - (strw>>1);
  271. int sy = (height>>1) - (strh>>1);
  272. XmStringDraw (d, this->dbl_buffer, NotebookTab::FontList,
  273. this->label, gc, sx,sy, width, XmALIGNMENT_BEGINNING,
  274. XmSTRING_DIRECTION_L_TO_R, NUL(XRectangle*));
  275. XtReleaseGC(w, gc);
  276. this->dirty = FALSE;
  277. }
  278. void NotebookTab::multiClickTimer()
  279. {
  280. if (this->multiclick_timer) {
  281. XtRemoveTimeOut(this->multiclick_timer);
  282. this->multiclick_timer = 0;
  283. this->multiClick();
  284. } else {
  285. XtAppContext apcxt = theApplication->getApplicationContext();
  286. int millis = XtGetMultiClickTime(XtDisplay(this->getRootWidget()));
  287. this->multiclick_timer = XtAppAddTimeOut(apcxt, millis, (XtTimerCallbackProc)
  288. NotebookTab_MultiClickTO, (XtPointer)this);
  289. }
  290. }
  291. extern "C" {
  292. void NotebookTab_ExposeCB (Widget w, XtPointer clientData, XtPointer)
  293. {
  294. NotebookTab* nt = (NotebookTab*)clientData;
  295. nt->expose();
  296. }
  297. void NotebookTab_ArmCB (Widget w, XtPointer clientData, XtPointer)
  298. {
  299. NotebookTab* nt = (NotebookTab*)clientData;
  300. nt->arm();
  301. }
  302. void NotebookTab_DisarmCB (Widget w, XtPointer clientData, XtPointer)
  303. {
  304. NotebookTab* nt = (NotebookTab*)clientData;
  305. nt->disarm();
  306. }
  307. void NotebookTab_ActivateCB (Widget w, XtPointer clientData, XtPointer callData)
  308. {
  309. NotebookTab* nt = (NotebookTab*)clientData;
  310. XmDrawnButtonCallbackStruct* cbs = (XmDrawnButtonCallbackStruct*)callData;
  311. if (cbs->click_count == 1)
  312. nt->activate();
  313. }
  314. void NotebookTab_ButtonEH(Widget w, XtPointer clientData, XEvent* xev, Boolean *doit)
  315. {
  316. *doit = TRUE;
  317. if (!xev) return ;
  318. if ((xev->type != ButtonPress) && (xev->type != ButtonRelease)) return ;
  319. if (xev->xbutton.button != 1) return ;
  320. NotebookTab* nt = (NotebookTab*)clientData;
  321. ASSERT(nt);
  322. if (nt->getState()) *doit = FALSE;
  323. if (xev->type == ButtonRelease)
  324. nt->multiClickTimer();
  325. }
  326. void NotebookTab_MultiClickTO (XtPointer clientData, XtIntervalId*)
  327. {
  328. NotebookTab* nt = (NotebookTab*)clientData;
  329. nt->multiclick_timer = 0;
  330. }
  331. void NotebookTab_RepaintTO (XtPointer clientData, XtIntervalId*)
  332. {
  333. NotebookTab* nt = (NotebookTab*)clientData;
  334. nt->repaint_timer = 0;
  335. nt->expose();
  336. }
  337. } // extern C