1 /* -*- mode: C++; tab-width: 4; c-basic-offset: 4; -*- */
2
3 /* AbiWord
4 * Copyright (C) 1998 AbiSource, Inc.
5 * Copyright (C) 2001-2003 Hubert Figuiere
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 (at your option) 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., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301 USA.
21 */
22
23 #include "ut_types.h"
24 #include "ut_assert.h"
25 #include "ut_debugmsg.h"
26
27 #include "gr_CocoaCairoGraphics.h"
28 #include "gr_Painter.h"
29
30 #include "ev_CocoaMouse.h"
31
32 #include "xap_App.h"
33 #include "xap_Frame.h"
34 #include "xap_CocoaFrame.h"
35
36 #include "ap_CocoaFrame.h"
37 #include "ap_CocoaFrameImpl.h"
38 #include "ap_CocoaTopRuler.h"
39 #include "ap_FrameData.h"
40
41 #define ENSUREP(p) do { UT_ASSERT(p); if (!p) goto Cleanup; } while (0)
42
43 /*****************************************************************/
44
45 @interface AP_CocoaTopRulerDelegate : NSObject <XAP_MouseEventDelegate>
46 {
47 AP_CocoaTopRuler* _xap;
48 }
49 - (void)setXAPOwner:(AP_CocoaTopRuler*)owner;
50 - (void)viewDidResize:(NSNotification*)notif;
51 @end
52
53
AP_CocoaTopRuler(XAP_Frame * pFrame)54 AP_CocoaTopRuler::AP_CocoaTopRuler(XAP_Frame * pFrame)
55 : AP_TopRuler(pFrame),
56 m_wTopRuler(nil),
57 m_rootWindow(nil),
58 m_delegate(nil)
59 {
60 m_wTopRuler = [(AP_CocoaFrameController *)(static_cast<XAP_CocoaFrameImpl *>(m_pFrame->getFrameImpl())->_getController()) getHRuler];
61 }
62
~AP_CocoaTopRuler(void)63 AP_CocoaTopRuler::~AP_CocoaTopRuler(void)
64 {
65 static_cast<GR_CocoaCairoGraphics *>(m_pG)->_setUpdateCallback (NULL, NULL);
66 DELETEP(m_pG);
67 if (m_delegate) {
68 [[NSNotificationCenter defaultCenter] removeObserver:m_delegate];
69 [m_wTopRuler setEventDelegate:nil];
70 [m_delegate release];
71 }
72 }
73
setView(AV_View * pView)74 void AP_CocoaTopRuler::setView(AV_View * pView)
75 {
76 AP_TopRuler::setView(pView);
77
78 if (m_delegate)
79 return;
80
81 DELETEP(m_pG);
82
83 GR_CocoaCairoAllocInfo ai(m_wTopRuler);
84 GR_CocoaCairoGraphics * pG = (GR_CocoaCairoGraphics *) XAP_App::getApp()->newGraphics(ai);
85 UT_ASSERT(pG);
86 m_pG = pG;
87
88 m_delegate = [[AP_CocoaTopRulerDelegate alloc] init];
89 [m_wTopRuler setEventDelegate:m_delegate];
90 [m_delegate setXAPOwner:this];
91 [[NSNotificationCenter defaultCenter] addObserver:m_delegate
92 selector:@selector(viewDidResize:)
93 name:NSViewFrameDidChangeNotification object:m_wTopRuler];
94
95 pG->_setUpdateCallback(&_graphicsUpdateCB, (void *)this);
96 pG->setGrabCursor(GR_Graphics::GR_CURSOR_LEFTRIGHT);
97
98 NSRect bounds = [m_wTopRuler bounds];
99 setWidth(lrintf(bounds.size.width));
100 setHeight(lrintf(bounds.size.height));
101 }
102
getWidgetPosition(int * x,int * y)103 void AP_CocoaTopRuler::getWidgetPosition(int * x, int * y)
104 {
105 UT_ASSERT(x && y);
106
107 NSRect theBounds = [m_wTopRuler bounds];
108 *x = (int)theBounds.size.width;
109 *y = (int)theBounds.size.height;
110 }
111
getRootWindow(void)112 NSWindow * AP_CocoaTopRuler::getRootWindow(void)
113 {
114 // TODO move this function somewhere more logical, like
115 // TODO the XAP_Frame level, since that's where the
116 // TODO root window is common to all descendants.
117 if (m_rootWindow)
118 return m_rootWindow;
119
120 m_rootWindow = [m_wTopRuler window];
121 return m_rootWindow;
122 }
123
124 #if 0
125 void AP_CocoaTopRuler::_drawMarginProperties(const UT_Rect * /*pClipRect*/, AP_TopRulerInfo * pInfo, GR_Graphics::GR_Color3D /*clr*/)
126 {
127 if (!m_pG)
128 return;
129
130 UT_Rect rLeft;
131 UT_Rect rRight;
132
133 _getMarginMarkerRects(pInfo, rLeft, rRight);
134
135 GR_Painter painter(m_pG);
136
137 GR_CocoaCairoGraphics * pG = static_cast<GR_CocoaCairoGraphics *>(m_pG);
138
139 UT_sint32 l = rLeft.left;
140 UT_sint32 t = rLeft.top;
141
142 UT_Point control[4];
143
144 control[0].x = l + 0;
145 control[0].y = t + 0;
146 control[1].x = l + 0;
147 control[1].y = t + 6;
148 control[2].x = l + 6;
149 control[2].y = t + 6;
150 control[3].x = l + 6;
151 control[3].y = t + 0;
152
153 UT_RGBColor lineColor;
154 GR_CocoaCairoGraphics::_utNSColorToRGBColor([NSColor knobColor], lineColor);
155
156 UT_RGBColor fillColor;
157 fillColor = pG->HBlue();
158
159 pG->polygon(fillColor, control, 4);
160 pG->setColor(lineColor);
161 pG->polyLine(control, 4);
162
163 l = rRight.left;
164 t = rRight.top;
165
166 pG->polygon(fillColor, control, 4);
167 pG->polyLine(control, 4);
168 }
169
170 void AP_CocoaTopRuler::_drawLeftIndentMarker(UT_Rect & rect, bool bFilled)
171 {
172 if (!m_pG)
173 return;
174
175 UT_sint32 l = rect.left;
176 UT_sint32 t = rect.top;
177
178 fl_BlockLayout * pBlock = (static_cast<FV_View *>(m_pView))->getCurrentBlock();
179
180 bool bRTL = pBlock ? (pBlock->getDominantDirection() == UT_BIDI_RTL) : false;
181
182 GR_Painter painter(m_pG);
183
184 GR_CocoaCairoGraphics * pG = static_cast<GR_CocoaCairoGraphics *>(m_pG);
185
186 UT_Point control[5];
187
188 control[0].x = l + 10;
189 control[0].y = t + 8;
190 control[1].x = l + 10;
191 control[1].y = t + 5;
192 control[2].x = l + 5;
193 control[2].y = t + 0;
194 control[3].x = l + 0;
195 control[3].y = t + 5;
196 control[4].x = l + 0;
197 control[4].y = t + 8;
198
199 UT_RGBColor lineColor;
200 GR_CocoaCairoGraphics::_utNSColorToRGBColor([NSColor knobColor], lineColor);
201
202 UT_RGBColor fillColor;
203
204 if (bFilled)
205 fillColor = pG->HBlue();
206 else
207 GR_CocoaCairoGraphics::_utNSColorToRGBColor([NSColor whiteColor], fillColor);
208
209 pG->polygon(fillColor, control, 5);
210 pG->setColor(lineColor);
211 pG->polyLine(control, 5);
212
213 if (!bRTL)
214 {
215 control[0].x = l + 10;
216 control[0].y = t + 9;
217 control[1].x = l + 0;
218 control[1].y = t + 9;
219 control[2].x = l + 0;
220 control[2].y = t + 14;
221 control[3].x = l + 10;
222 control[3].y = t + 14;
223
224 pG->polygon(fillColor, control, 4);
225 pG->setColor(lineColor);
226 pG->polyLine(control, 4);
227 }
228 }
229
230 void AP_CocoaTopRuler::_drawRightIndentMarker(UT_Rect & rect, bool bFilled)
231 {
232 if (!m_pG)
233 return;
234
235 UT_sint32 l = rect.left;
236 UT_sint32 t = rect.top;
237
238 fl_BlockLayout * pBlock = (static_cast<FV_View *>(m_pView))->getCurrentBlock();
239
240 bool bRTL = pBlock ? (pBlock->getDominantDirection() == UT_BIDI_RTL) : false;
241
242 GR_Painter painter(m_pG);
243
244 GR_CocoaCairoGraphics * pG = static_cast<GR_CocoaCairoGraphics *>(m_pG);
245
246 UT_Point control[5];
247
248 control[0].x = l + 10;
249 control[0].y = t + 8;
250 control[1].x = l + 10;
251 control[1].y = t + 5;
252 control[2].x = l + 5;
253 control[2].y = t + 0;
254 control[3].x = l + 0;
255 control[3].y = t + 5;
256 control[4].x = l + 0;
257 control[4].y = t + 8;
258
259 UT_RGBColor lineColor;
260 GR_CocoaCairoGraphics::_utNSColorToRGBColor([NSColor knobColor], lineColor);
261
262 UT_RGBColor fillColor;
263
264 if (bFilled)
265 fillColor = pG->HBlue();
266 else
267 GR_CocoaCairoGraphics::_utNSColorToRGBColor([NSColor whiteColor], fillColor);
268
269 pG->polygon(fillColor, control, 5);
270 pG->setColor(lineColor);
271 pG->polyLine(control, 5);
272
273 if (bRTL)
274 {
275 control[0].x = l + 10;
276 control[0].y = t + 9;
277 control[1].x = l + 0;
278 control[1].y = t + 9;
279 control[2].x = l + 0;
280 control[2].y = t + 14;
281 control[3].x = l + 10;
282 control[3].y = t + 14;
283
284 pG->polygon(fillColor, control, 4);
285 pG->setColor(lineColor);
286 pG->polyLine(control, 4);
287 }
288 }
289
290 void AP_CocoaTopRuler::_drawFirstLineIndentMarker(UT_Rect & rect, bool bFilled)
291 {
292 if (!m_pG)
293 return;
294
295 UT_sint32 l = rect.left;
296 UT_sint32 t = rect.top;
297
298 GR_Painter painter(m_pG);
299
300 GR_CocoaCairoGraphics * pG = static_cast<GR_CocoaCairoGraphics *>(m_pG);
301
302 UT_Point control[5];
303
304 control[0].x = l + 0;
305 control[0].y = t + 0;
306 control[1].x = l + 0;
307 control[1].y = t + 3;
308 control[2].x = l + 5;
309 control[2].y = t + 8;
310 control[3].x = l + 10;
311 control[3].y = t + 3;
312 control[4].x = l + 10;
313 control[4].y = t + 0;
314
315 UT_RGBColor lineColor;
316 GR_CocoaCairoGraphics::_utNSColorToRGBColor([NSColor knobColor], lineColor);
317
318 UT_RGBColor fillColor;
319
320 if (bFilled)
321 fillColor = pG->HBlue();
322 else
323 GR_CocoaCairoGraphics::_utNSColorToRGBColor([NSColor whiteColor], fillColor);
324
325 pG->polygon(fillColor, control, 5);
326 pG->setColor(lineColor);
327 pG->polyLine(control, 5);
328 }
329
330 void AP_CocoaTopRuler::_drawColumnGapMarker(UT_Rect & rect)
331 {
332 if (!m_pG)
333 return;
334
335 UT_sint32 l = rect.left;
336 UT_sint32 t = rect.top;
337
338 UT_sint32 w = m_pG->tdu(rect.width);
339
340 GR_Painter painter(m_pG);
341
342 GR_CocoaCairoGraphics * pG = static_cast<GR_CocoaCairoGraphics *>(m_pG);
343
344 UT_Point control[6];
345
346 control[0].x = l + w - 1;
347 control[0].y = t + 0;
348 control[1].x = l + 1;
349 control[1].y = t + 0;
350 control[2].x = l + 1;
351 control[2].y = t + 6;
352 control[3].x = l + 4;
353 control[3].y = t + 3;
354 control[4].x = l + w - 4;
355 control[4].y = t + 3;
356 control[5].x = l + w - 1;
357 control[5].y = t + 6;
358
359 UT_RGBColor lineColor;
360 GR_CocoaCairoGraphics::_utNSColorToRGBColor([NSColor knobColor], lineColor);
361 UT_RGBColor fillColor;
362 fillColor = pG->HBlue();
363
364 pG->polygon(fillColor, control, 6);
365 pG->setColor(lineColor);
366 pG->polyLine(control, 6);
367 }
368
369 void AP_CocoaTopRuler::_drawCellMark(UT_Rect * prDrag, bool bUp)
370 {
371 if (!m_pG || !prDrag)
372 return;
373
374 UT_sint32 l = prDrag->left;
375 UT_sint32 t = prDrag->top;
376
377 UT_sint32 w = m_pG->tdu(prDrag->width);
378 UT_sint32 h = m_pG->tdu(prDrag->height);
379
380 GR_Painter painter(m_pG);
381
382 GR_CocoaCairoGraphics * pG = static_cast<GR_CocoaCairoGraphics *>(m_pG);
383
384 UT_Point control[4];
385
386 control[0].x = l + 1;
387 control[0].y = t + 1;
388 control[1].x = l + 1;
389 control[1].y = t + h - 1;
390 control[2].x = l + w - 1;
391 control[2].y = t + h - 1;
392 control[3].x = l + w - 1;
393 control[3].y = t + 1;
394
395 UT_RGBColor lineColor;
396 GR_CocoaCairoGraphics::_utNSColorToRGBColor([NSColor knobColor], lineColor);
397
398 UT_RGBColor fillColor;
399 if (bUp)
400 fillColor = pG->HGrey();
401 else
402 GR_CocoaCairoGraphics::_utNSColorToRGBColor([NSColor whiteColor], fillColor);
403
404 pG->polygon(fillColor, control, 4);
405 pG->setColor(lineColor);
406 pG->polyLine(control, 4);
407 }
408 #endif
409
_graphicsUpdateCB(NSRect * aRect,GR_CocoaCairoGraphics * pG,void * param)410 bool AP_CocoaTopRuler::_graphicsUpdateCB(NSRect * aRect, GR_CocoaCairoGraphics *pG, void* param)
411 {
412 // a static function
413 AP_CocoaTopRuler * pCocoaTopRuler = (AP_CocoaTopRuler *)param;
414 if (!pCocoaTopRuler)
415 return false;
416
417 UT_Rect rClip;
418 rClip.left = aRect->origin.x;
419 rClip.top = aRect->origin.y;
420 rClip.width = aRect->size.width;
421 rClip.height = aRect->size.height;
422 xxx_UT_DEBUGMSG(("Cocoa in topruler expose painting area: left=%d, top=%d, width=%d, height=%d\n", rClip.left, rClip.top, rClip.width, rClip.height));
423 if(pG != NULL)
424 {
425 // pCocoaTopRuler->getGraphics()->doRepaint(&rClip);
426 pCocoaTopRuler->draw(&rClip);
427 }
428 else {
429 return false;
430 }
431 return true;
432 }
433
434 /*****************************************************************/
435
436
437 @implementation AP_CocoaTopRulerDelegate
438
439 - (void)dealloc
440 {
441 [[NSNotificationCenter defaultCenter] removeObserver:self];
442 [super dealloc];
443 }
444
445 - (void)setXAPOwner:(AP_CocoaTopRuler*)owner
446 {
447 _xap = owner;
448 }
449
450 - (void)viewDidResize:(NSNotification*)notif
451 {
452 NSRect bounds = [[notif object] bounds];
453 _xap->setWidth(lrintf(bounds.size.width));
454 _xap->setHeight(lrintf(bounds.size.height));
455 // _xap->draw(NULL);
456 }
457
458 - (void)mouseDown:(NSEvent *)theEvent from:(id)sender
459 {
460 EV_EditModifierState ems = 0;
461 EV_EditMouseButton emb = 0;
462 bool rightBtn = false;
463
464 ems = EV_CocoaMouse::_convertModifierState([theEvent modifierFlags], rightBtn);
465 emb = EV_CocoaMouse::_convertMouseButton([theEvent buttonNumber], rightBtn);
466
467 NSPoint pt = [theEvent locationInWindow];
468 pt = [sender convertPoint:pt fromView:nil];
469 GR_CocoaCairoGraphics* pGr = dynamic_cast<GR_CocoaCairoGraphics*>(_xap->getGraphics());
470 if (!pGr->_isFlipped()) {
471 pt.y = [sender bounds].size.height - pt.y;
472 }
473 _xap->mousePress(ems, emb, (UT_uint32)pGr->tluD(pt.x), (UT_uint32)pGr->tluD(pt.y));
474 }
475
476
477 - (void)mouseDragged:(NSEvent *)theEvent from:(id)sender
478 {
479 EV_EditModifierState ems = 0;
480 bool rightBtn = false;
481
482 ems = EV_CocoaMouse::_convertModifierState([theEvent modifierFlags], rightBtn);
483
484 // Map the mouse into coordinates relative to our window.
485 NSPoint pt = [theEvent locationInWindow];
486 pt = [sender convertPoint:pt fromView:nil];
487 GR_CocoaCairoGraphics* pGr = dynamic_cast<GR_CocoaCairoGraphics*>(_xap->getGraphics());
488 if (!pGr->_isFlipped()) {
489 pt.y = [sender bounds].size.height - pt.y;
490 }
491 _xap->mouseMotion(ems, (UT_sint32)pGr->tluD(pt.x), (UT_sint32)pGr->tluD(pt.y));
492 _xap->isMouseOverTab((UT_uint32)pGr->tluD(pt.x),(UT_uint32)pGr->tluD(pt.y));
493 }
494
495
496 - (void)mouseUp:(NSEvent *)theEvent from:(id)sender
497 {
498 EV_EditModifierState ems = 0;
499 EV_EditMouseButton emb = 0;
500 bool rightBtn = false;
501
502 ems = EV_CocoaMouse::_convertModifierState([theEvent modifierFlags], rightBtn);
503 emb = EV_CocoaMouse::_convertMouseButton([theEvent buttonNumber], rightBtn);
504
505 // Map the mouse into coordinates relative to our window.
506 NSPoint pt = [theEvent locationInWindow];
507 pt = [sender convertPoint:pt fromView:nil];
508 GR_CocoaCairoGraphics* pGr = dynamic_cast<GR_CocoaCairoGraphics*>(_xap->getGraphics());
509 if (!pGr->_isFlipped()) {
510 pt.y = [sender bounds].size.height - pt.y;
511 }
512 _xap->mouseRelease(ems, emb, (UT_sint32)pGr->tluD(pt.x), (UT_sint32)pGr->tluD(pt.y));
513 }
514 @end
515