3 #define MIN_DOC_WIDTH 10
5 typedef struct W_Ruler
{
8 W_View
*pview
; /* the parent's view (for drawing the line) */
10 WMAction
*moveAction
; /* what to when while moving */
11 WMAction
*releaseAction
; /* what to do when released */
16 WMRulerMargins margins
;
18 int motion
; /* the position of the _moving_ marker(s) */
19 int end
; /* the last tick on the baseline (restrict markers to it) */
24 unsigned int buttonPressed
:1;
25 /* 0, 1, 2, 3, 4, 5, 6 */
26 unsigned int whichMarker
:3; /* none, left, right, first, body, tabstop, both */
27 unsigned int RESERVED
:28;
33 /* Marker for left margin
41 drawLeftMarker(Ruler
*rPtr
)
44 int xpos
= (rPtr
->flags
.whichMarker
==1?
45 rPtr
->motion
:rPtr
->margins
.left
);
47 XDrawLine(rPtr
->view
->screen
->display
, rPtr
->drawBuffer
,
48 rPtr
->fg
, xpos
, 8, xpos
, 22);
51 points
[1].x
= points
[0].x
+6;
53 points
[2].x
= points
[0].x
+6;
55 points
[3].x
= points
[0].x
;
57 XFillPolygon (rPtr
->view
->screen
->display
, rPtr
->drawBuffer
,
58 rPtr
->fg
, points
, 4, Convex
, CoordModeOrigin
);
61 /* Marker for right margin
70 drawRightMarker(Ruler
*rPtr
)
73 int xpos
= (rPtr
->flags
.whichMarker
==2?
74 rPtr
->motion
:rPtr
->margins
.right
);
76 XDrawLine(rPtr
->view
->screen
->display
, rPtr
->drawBuffer
,
77 rPtr
->fg
, xpos
, 8, xpos
, 22);
80 points
[1].x
= points
[0].x
-6;
82 points
[2].x
= points
[0].x
-6;
84 points
[3].x
= points
[0].x
;
86 XFillPolygon (rPtr
->view
->screen
->display
, rPtr
->drawBuffer
,
87 rPtr
->fg
, points
, 4, Convex
, CoordModeOrigin
);
91 /* Marker for first line only
96 drawFirstMarker(Ruler
*rPtr
)
98 int xpos
= ((rPtr
->flags
.whichMarker
==3 || rPtr
->flags
.whichMarker
==6)?
99 rPtr
->motion
:rPtr
->margins
.first
);
100 XFillRectangle(rPtr
->view
->screen
->display
, rPtr
->drawBuffer
,
101 rPtr
->fg
, xpos
-5, 10, 11, 5);
102 XDrawLine(rPtr
->view
->screen
->display
, rPtr
->drawBuffer
,
103 rPtr
->fg
, xpos
, 12, xpos
, 22);
106 /* Marker for rest of body
111 drawBodyMarker(Ruler
*rPtr
)
114 int xpos
= ((rPtr
->flags
.whichMarker
==4 || rPtr
->flags
.whichMarker
==6)?
115 rPtr
->motion
:rPtr
->margins
.body
);
116 points
[0].x
= xpos
-5;
118 points
[1].x
= points
[0].x
+11;
120 points
[2].x
= points
[0].x
+5;
122 XFillPolygon (rPtr
->view
->screen
->display
, rPtr
->drawBuffer
,
123 rPtr
->fg
, points
, 3, Convex
, CoordModeOrigin
);
127 createDrawBuffer(Ruler
*rPtr
)
130 XFreePixmap(rPtr
->view
->screen
->display
, rPtr
->drawBuffer
);
131 rPtr
->drawBuffer
= XCreatePixmap(rPtr
->view
->screen
->display
,
132 rPtr
->view
->window
, rPtr
->view
->size
.width
, 40,
133 rPtr
->view
->screen
->depth
);
134 XFillRectangle(rPtr
->view
->screen
->display
, rPtr
->drawBuffer
,
135 rPtr
->bg
, 0, 0, rPtr
->view
->size
.width
, 40);
139 drawRulerOnPixmap(Ruler
*rPtr
)
143 int marks
[9] = {11, 3, 5, 3, 7, 3, 5, 3};
145 if(!rPtr
->drawBuffer
)
146 createDrawBuffer(rPtr
);
148 XFillRectangle(rPtr
->view
->screen
->display
, rPtr
->drawBuffer
,
149 rPtr
->bg
, 0, 0, rPtr
->view
->size
.width
, 40);
152 WMDrawString(rPtr
->view
->screen
, rPtr
->drawBuffer
,
153 rPtr
->fg
, rPtr
->font
, rPtr
->margins
.left
+2, 26, "0 inches", 10);
157 w
= rPtr
->view
->size
.width
- rPtr
->margins
.left
;
159 XDrawLine(rPtr
->view
->screen
->display
, rPtr
->drawBuffer
,
160 rPtr
->fg
, rPtr
->margins
.left
+m
, 23,
161 rPtr
->margins
.left
+m
, marks
[i
%8]+23);
164 snprintf(c
,3,"%d",++j
);
166 snprintf(c
,3,"%2d",++j
);
167 WMDrawString(rPtr
->view
->screen
, rPtr
->drawBuffer
,
168 rPtr
->fg
, rPtr
->font
, rPtr
->margins
.left
+2+m
, 26, c
, 2);
173 rPtr
->end
= rPtr
->margins
.left
+m
-10;
174 if(rPtr
->margins
.right
> rPtr
->end
)
175 rPtr
->margins
.right
= rPtr
->end
;
177 XDrawLine(rPtr
->view
->screen
->display
, rPtr
->drawBuffer
,
178 rPtr
->fg
, rPtr
->margins
.left
, 22, rPtr
->margins
.left
+m
-10, 22);
180 drawLeftMarker(rPtr
);
181 drawRightMarker(rPtr
);
182 drawFirstMarker(rPtr
);
183 drawBodyMarker(rPtr
);
187 paintRuler(Ruler
*rPtr
)
189 WMScreen
*screen
= rPtr
->view
->screen
;
190 if(1||!rPtr
->drawBuffer
) { //first exposure
191 drawRulerOnPixmap(rPtr
);
194 XCopyArea(rPtr
->view
->screen
->display
, rPtr
->drawBuffer
,
195 rPtr
->view
->window
, rPtr
->bg
, 0, 0, rPtr
->view
->size
.width
, 40,
200 verifyMarkerMove(Ruler
*rPtr
, int x
)
202 if(rPtr
->flags
.whichMarker
<1 || rPtr
->flags
.whichMarker
>6)
205 switch(rPtr
->flags
.whichMarker
) {
207 if( x
> rPtr
->margins
.right
- 10
208 || rPtr
->margins
.body
+ x
> rPtr
->margins
.right
-MIN_DOC_WIDTH
209 || rPtr
->margins
.first
+ x
> rPtr
->margins
.right
-MIN_DOC_WIDTH
215 if( x
< rPtr
->margins
.first
+MIN_DOC_WIDTH
216 || x
< rPtr
->margins
.body
+MIN_DOC_WIDTH
217 || x
< rPtr
->margins
.left
+MIN_DOC_WIDTH
218 || x
> rPtr
->end
) //rPtr->view->size.width)
223 if( x
>= rPtr
->margins
.right
-MIN_DOC_WIDTH
224 || x
< rPtr
->margins
.left
)
229 if( x
>= rPtr
->margins
.right
-MIN_DOC_WIDTH
230 || x
< rPtr
->margins
.left
)
235 if( x
>= rPtr
->margins
.right
-MIN_DOC_WIDTH
236 || x
< rPtr
->margins
.left
)
240 default: return False
;
249 whichMarker(Ruler
*rPtr
, int x
, int y
)
251 if(x
<rPtr
->offset
|| y
>22)
254 if( rPtr
->margins
.left
-x
>= -6 && y
<= 9
255 && (rPtr
->margins
.left
-x
<=0) && y
>=4) {
256 rPtr
->motion
= rPtr
->margins
.left
;
260 if(rPtr
->margins
.right
-x
>= -1 && y
<= 11
261 && rPtr
->margins
.right
-x
<=5 && y
>=4) {
262 rPtr
->motion
= rPtr
->margins
.right
;
267 /* both first and body? */
268 if( rPtr
->margins
.first
-x
<= 4 && rPtr
->margins
.first
-x
>= -5
269 && rPtr
->margins
.body
-x
<= 4 && rPtr
->margins
.body
-x
>= -5
271 rPtr
->motion
= rPtr
->margins
.first
;
276 if(rPtr
->margins
.first
-x
<= 4 && y
<=15
277 && rPtr
->margins
.first
-x
>= -5 && y
>=10) {
278 rPtr
->motion
= rPtr
->margins
.first
;
282 if( rPtr
->margins
.body
-x
<= 4 && y
<=21 &&
283 rPtr
->margins
.body
-x
>= -5 && y
>=17) {
284 rPtr
->motion
= rPtr
->margins
.body
;
297 handleEvents(XEvent
*event
, void *data
)
299 Ruler
*rPtr
= (Ruler
*)data
;
300 Display
*dpy
= event
->xany
.display
;
302 switch (event
->type
) {
308 if(rPtr
->flags
.buttonPressed
309 && (event
->xmotion
.state
& Button1Mask
)) {
310 if(verifyMarkerMove(rPtr
, event
->xmotion
.x
)){
311 GC gc
= WMColorGC(WMDarkGrayColor(rPtr
->view
->screen
));
314 (rPtr
->moveAction
)(rPtr
, rPtr
->clientData
);
315 XSetLineAttributes(rPtr
->view
->screen
->display
, gc
, 1,
316 LineSolid
, CapNotLast
, JoinMiter
);
317 XDrawLine(rPtr
->pview
->screen
->display
,
319 gc
, rPtr
->motion
+1, 40,
320 rPtr
->motion
+1, rPtr
->pview
->size
.height
-5);
326 if(event
->xbutton
.button
!= Button1
)
328 rPtr
->flags
.buttonPressed
= True
;
329 rPtr
->flags
.whichMarker
=
330 whichMarker(rPtr
, event
->xmotion
.x
,
335 if(event
->xbutton
.button
!= Button1
)
337 rPtr
->flags
.buttonPressed
= False
;
338 switch(rPtr
->flags
.whichMarker
) {
340 int change
= rPtr
->margins
.left
-rPtr
->motion
;
341 rPtr
->margins
.first
-=change
;
342 rPtr
->margins
.body
-= change
;
343 rPtr
->margins
.left
= rPtr
->motion
;
344 paintRuler(rPtr
); break;
346 case 2: rPtr
->margins
.right
= rPtr
->motion
; break;
347 case 3: rPtr
->margins
.first
= rPtr
->motion
; break;
348 case 4: rPtr
->margins
.body
= rPtr
->motion
; break;
349 case 6: rPtr
->margins
.first
= rPtr
->margins
.body
350 = rPtr
->motion
; break;
352 if(rPtr
->releaseAction
)
353 (rPtr
->releaseAction
)(rPtr
, rPtr
->clientData
);
359 rulerDidResize(W_ViewDelegate
*self
, WMView
*view
)
361 Ruler
*rPtr
= (Ruler
*)view
->self
;
363 createDrawBuffer(rPtr
);
369 W_ViewDelegate _RulerViewDelegate
=
380 WMCreateRuler(WMWidget
*parent
)
382 Ruler
*rPtr
= wmalloc(sizeof(Ruler
));
383 unsigned int w
= WMWidgetWidth(parent
);
385 memset(rPtr
, 0, sizeof(Ruler
));
387 rPtr
->widgetClass
= WC_Ruler
;
389 rPtr
->view
= W_CreateView(W_VIEW(parent
));
394 rPtr
->view
->self
= rPtr
;
396 rPtr
->drawBuffer
= (Pixmap
) NULL
;
398 W_ResizeView(rPtr
->view
, w
, 40);
400 WMCreateEventHandler(rPtr
->view
, ExposureMask
|StructureNotifyMask
401 |EnterWindowMask
|LeaveWindowMask
|FocusChangeMask
402 |ButtonReleaseMask
|ButtonPressMask
|KeyReleaseMask
403 |KeyPressMask
|Button1MotionMask
, handleEvents
, rPtr
);
405 rPtr
->view
->delegate
= &_RulerViewDelegate
;
407 rPtr
->bg
= WMColorGC(WMGrayColor(rPtr
->view
->screen
));
408 rPtr
->fg
= WMColorGC(WMBlackColor(rPtr
->view
->screen
));
409 rPtr
->font
= WMSystemFontOfSize(rPtr
->view
->screen
, 8);
412 rPtr
->margins
.left
= 22;
413 rPtr
->margins
.body
= 22;
414 rPtr
->margins
.first
= 42;
415 rPtr
->margins
.right
= (w
<502?w
:502);
417 rPtr
->flags
.whichMarker
= 0; /* none */
418 rPtr
->flags
.buttonPressed
= False
;
420 rPtr
->moveAction
= NULL
;
421 rPtr
->releaseAction
= NULL
;
423 rPtr
->pview
= W_VIEW(parent
);
430 WMSetRulerMargins(WMRuler
*rPtr
, WMRulerMargins margins
)
434 rPtr
->margins
.left
= margins
.left
+ rPtr
->offset
;
435 rPtr
->margins
.right
= margins
.right
+ rPtr
->offset
;
436 rPtr
->margins
.first
= margins
.first
+ rPtr
->offset
;
437 rPtr
->margins
.body
= margins
.body
+ rPtr
->offset
;
438 rPtr
->margins
.tabs
= margins
.tabs
; //for loop
444 WMGetRulerMargins(WMRuler
*rPtr
)
446 WMRulerMargins margins
;
450 margins
.left
= rPtr
->margins
.left
- rPtr
->offset
;
451 margins
.right
= rPtr
->margins
.right
- rPtr
->offset
;
452 margins
.first
= rPtr
->margins
.first
- rPtr
->offset
;
453 margins
.body
= rPtr
->margins
.body
- rPtr
->offset
;
455 margins
.tabs
= rPtr
->margins
.tabs
;
457 return rPtr
->margins
;
461 WMSetRulerOffset(WMRuler
*rPtr
, int pixels
)
463 if(!rPtr
|| pixels
<0 || pixels
+MIN_DOC_WIDTH
>=rPtr
->view
->size
.width
)
465 rPtr
->offset
= pixels
;
466 //rulerDidResize(rPtr, rPtr->view);
470 WMGetRulerOffset(WMRuler
*rPtr
)
478 WMSetRulerReleaseAction(WMRuler
*rPtr
, WMAction
*action
, void *clientData
)
483 rPtr
->releaseAction
= action
;
484 rPtr
->clientData
= clientData
;
488 WMSetRulerMoveAction(WMRuler
*rPtr
, WMAction
*action
, void *clientData
)
493 rPtr
->moveAction
= action
;
494 rPtr
->clientData
= clientData
;
497 /* _which_ one was released */
499 WMGetReleasedRulerMargin(WMRuler
*rPtr
)
503 return rPtr
->flags
.whichMarker
;
506 /* _which_ one is being grabbed */
508 WMGetGrabbedRulerMargin(WMRuler
*rPtr
)
512 return rPtr
->flags
.whichMarker
;