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