Stroika Library 3.0d18
 
Loading...
Searching...
No Matches
RulerToolbar.cpp
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4
5#include "Stroika/Foundation/StroikaPreComp.h"
6
7#include <afxpriv.h> // For WM_SIZEPARENT
8#include <afxwin.h> // MFC core and standard components
9
10#include "LedItResources.h"
11#include "LedItView.h"
12
13#include "RulerToolbar.h"
14
15using namespace Stroika::Foundation;
16using namespace Stroika::Frameworks::Led;
17using namespace Stroika::Frameworks::Led::Platform;
18using namespace Stroika::Frameworks::Led::StyledTextIO;
19
20using RulerItem = RulerBar::RulerItem;
21using CComboRulerItem = RulerBar::CComboRulerItem;
22using CTabRulerItem = RulerBar::CTabRulerItem;
23
24#define HEIGHT 17
25#define RULERBARHEIGHT 17
26
27RulerItem::RulerItem (UINT nBitmapID)
28{
29 m_nAlignment = TA_CENTER;
30 m_pDC = NULL;
31 m_bTrack = FALSE;
32 m_hbm = NULL;
33 m_hbmMask = NULL;
34 if (nBitmapID != 0) {
35 m_hbmMask = ::LoadBitmap (AfxFindResourceHandle (MAKEINTRESOURCE (nBitmapID + 1), RT_BITMAP), MAKEINTRESOURCE (nBitmapID + 1));
36 ASSERT (m_hbmMask != NULL);
37 VERIFY (LoadMaskedBitmap (MAKEINTRESOURCE (nBitmapID)));
38 BITMAP bm;
39 ::GetObject (m_hbm, sizeof (BITMAP), &bm);
40 m_size = CSize (bm.bmWidth, bm.bmHeight);
41 }
42}
43
44RulerItem::~RulerItem ()
45{
46 if (m_hbm != NULL)
47 ::DeleteObject (m_hbm);
48 if (m_hbmMask != NULL)
49 ::DeleteObject (m_hbmMask);
50}
51
52BOOL RulerItem::LoadMaskedBitmap (LPCTSTR lpszResourceName)
53{
54 ASSERT (lpszResourceName != NULL);
55
56 if (m_hbm != NULL)
57 ::DeleteObject (m_hbm);
58
59 HINSTANCE hInst = AfxFindResourceHandle (lpszResourceName, RT_BITMAP);
60 HRSRC hRsrc = ::FindResource (hInst, lpszResourceName, RT_BITMAP);
61 if (hRsrc == NULL)
62 return FALSE;
63
64 m_hbm = AfxLoadSysColorBitmap (hInst, hRsrc);
65 return (m_hbm != NULL);
66}
67
68void RulerItem::SetHorzPosTwips (int nXPos)
69{
70 if (GetHorzPosTwips () != nXPos) {
71 if (m_bTrack)
72 DrawFocusLine ();
73 Invalidate ();
74 m_nXPosTwips = nXPos;
75 Invalidate ();
76 if (m_bTrack)
77 DrawFocusLine ();
78 }
79}
80
81void RulerItem::TrackHorzPosTwips (int nXPos, BOOL /*bOnRuler*/)
82{
83 int nMin = GetMin ();
84 int nMax = GetMax ();
85 if (nXPos < nMin)
86 nXPos = nMin;
87 if (nXPos > nMax)
88 nXPos = nMax;
89 SetHorzPosTwips (nXPos);
90}
91
92void RulerItem::DrawFocusLine ()
93{
94 if (GetHorzPosTwips () != 0) {
95 m_rcTrack.left = m_rcTrack.right = GetHorzPosPix ();
96 ASSERT (m_pDC != NULL);
97 int nLeft = m_pRuler->XRulerToClient (m_rcTrack.left);
98 m_pDC->MoveTo (nLeft, m_rcTrack.top);
99 m_pDC->LineTo (nLeft, m_rcTrack.bottom);
100 }
101}
102
103void RulerItem::SetTrack (BOOL b)
104{
105 m_bTrack = b;
106
107 if (m_pDC != NULL) { // just in case we lost focus Capture somewhere
108 DrawFocusLine ();
109 m_pDC->RestoreDC (-1);
110 delete m_pDC;
111 m_pDC = NULL;
112 }
113 if (m_bTrack) {
114 CView* pView = m_pRuler->GetView ();
115 ASSERT (pView != NULL);
116 pView->GetClientRect (&m_rcTrack);
117 m_pDC = new CWindowDC (pView);
118 m_pDC->SaveDC ();
119 m_pDC->SelectObject (&m_pRuler->penFocusLine);
120 m_pDC->SetROP2 (R2_XORPEN);
121 DrawFocusLine ();
122 }
123}
124
125void RulerItem::Invalidate ()
126{
127 CRect rc = GetHitRectPix ();
128 m_pRuler->RulerToClient (rc.TopLeft ());
129 m_pRuler->RulerToClient (rc.BottomRight ());
130 m_pRuler->InvalidateRect (rc);
131}
132
133CRect RulerItem::GetHitRectPix ()
134{
135 int nx = GetHorzPosPix ();
136 return CRect (CPoint ((m_nAlignment == TA_CENTER) ? (nx - m_size.cx / 2)
137 : (m_nAlignment == TA_LEFT) ? nx
138 : nx - m_size.cx,
139 m_nYPosPix),
140 m_size);
141}
142
143void RulerItem::Draw (CDC& dc)
144{
145 CDC dcBitmap;
146 dcBitmap.CreateCompatibleDC (&dc);
147 CPoint pt (GetHorzPosPix (), GetVertPosPix ());
148
149 HGDIOBJ hbm = ::SelectObject (dcBitmap.m_hDC, m_hbmMask);
150
151 // do mask part
152 if (m_nAlignment == TA_CENTER)
153 dc.BitBlt (pt.x - m_size.cx / 2, pt.y, m_size.cx, m_size.cy, &dcBitmap, 0, 0, SRCAND);
154 else if (m_nAlignment == TA_LEFT)
155 dc.BitBlt (pt.x, pt.y, m_size.cx, m_size.cy, &dcBitmap, 0, 0, SRCAND);
156 else // TA_RIGHT
157 dc.BitBlt (pt.x - m_size.cx, pt.y, m_size.cx, m_size.cy, &dcBitmap, 0, 0, SRCAND);
158
159 // do image part
160 ::SelectObject (dcBitmap.m_hDC, m_hbm);
161
162 if (m_nAlignment == TA_CENTER)
163 dc.BitBlt (pt.x - m_size.cx / 2, pt.y, m_size.cx, m_size.cy, &dcBitmap, 0, 0, SRCINVERT);
164 else if (m_nAlignment == TA_LEFT)
165 dc.BitBlt (pt.x, pt.y, m_size.cx, m_size.cy, &dcBitmap, 0, 0, SRCINVERT);
166 else // TA_RIGHT
167 dc.BitBlt (pt.x - m_size.cx, pt.y, m_size.cx, m_size.cy, &dcBitmap, 0, 0, SRCINVERT);
168
169 ::SelectObject (dcBitmap.m_hDC, hbm);
170}
171
172CComboRulerItem::CComboRulerItem (UINT nBitmapID1, UINT nBitmapID2, RulerItem& item)
173 : RulerItem (nBitmapID1)
174 , m_secondary (nBitmapID2)
175 , m_link (item)
176{
177 m_bHitPrimary = TRUE;
178}
179
180BOOL CComboRulerItem::HitTestPix (CPoint pt)
181{
182 m_bHitPrimary = FALSE;
183 if (RulerItem::GetHitRectPix ().PtInRect (pt))
184 m_bHitPrimary = TRUE;
185 else
186 return m_secondary.HitTestPix (pt);
187 return TRUE;
188}
189
190void CComboRulerItem::Draw (CDC& dc)
191{
192 RulerItem::Draw (dc);
193 m_secondary.Draw (dc);
194}
195
196void CComboRulerItem::SetHorzPosTwips (int nXPos)
197{
198 if (m_bHitPrimary) // only change linked items by delta
199 m_link.SetHorzPosTwips (m_link.GetHorzPosTwips () + nXPos - GetHorzPosTwips ());
200 RulerItem::SetHorzPosTwips (nXPos);
201 m_secondary.SetHorzPosTwips (nXPos);
202}
203
204void CComboRulerItem::TrackHorzPosTwips (int nXPos, BOOL /*bOnRuler*/)
205{
206 int nMin = GetMin ();
207 int nMax = GetMax ();
208 if (nXPos < nMin)
209 nXPos = nMin;
210 if (nXPos > nMax)
211 nXPos = nMax;
212 SetHorzPosTwips (nXPos);
213}
214
215void CComboRulerItem::SetVertPos (int nYPos)
216{
217 m_secondary.SetVertPos (nYPos);
218 nYPos += m_secondary.GetHitRectPix ().Height ();
219 RulerItem::SetVertPos (nYPos);
220}
221
222void CComboRulerItem::SetAlignment (int nAlign)
223{
224 RulerItem::SetAlignment (nAlign);
225 m_secondary.SetAlignment (nAlign);
226}
227
228void CComboRulerItem::SetRuler (RulerBar* pRuler)
229{
230 m_pRuler = pRuler;
231 m_secondary.SetRuler (pRuler);
232}
233
234void CComboRulerItem::SetBounds (int nMin, int nMax)
235{
236 RulerItem::SetBounds (nMin, nMax);
237 m_secondary.SetBounds (nMin, nMax);
238}
239
240int CComboRulerItem::GetMin ()
241{
242 if (m_bHitPrimary) {
243 int nPDist = GetHorzPosTwips () - RulerItem::GetMin ();
244 int nLDist = m_link.GetHorzPosTwips () - m_link.GetMin ();
245 return GetHorzPosTwips () - min (nPDist, nLDist);
246 }
247 else
248 return RulerItem::GetMin ();
249}
250
251int CComboRulerItem::GetMax ()
252{
253 if (m_bHitPrimary) {
254 int nPDist = RulerItem::GetMax () - GetHorzPosTwips ();
255 int nLDist = m_link.GetMax () - m_link.GetHorzPosTwips ();
256 int nMinDist = (nPDist < nLDist) ? nPDist : nLDist;
257 return GetHorzPosTwips () + nMinDist;
258 }
259 else
260 return RulerItem::GetMax ();
261}
262
263void CTabRulerItem::TrackHorzPosTwips (int nXPos, BOOL bOnRuler)
264{
265 if (bOnRuler)
266 RulerItem::TrackHorzPosTwips (nXPos, bOnRuler);
267 else
268 RulerItem::TrackHorzPosTwips (0, bOnRuler);
269}
270
271BEGIN_MESSAGE_MAP (RulerBar, CControlBar)
272//{{AFX_MSG_MAP(RulerBar)
273ON_WM_LBUTTONDOWN ()
274ON_WM_LBUTTONUP ()
275ON_WM_MOUSEMOVE ()
276ON_WM_SYSCOLORCHANGE ()
277ON_WM_WINDOWPOSCHANGING ()
278ON_WM_SHOWWINDOW ()
279ON_WM_WINDOWPOSCHANGED ()
280//}}AFX_MSG_MAP
281ON_MESSAGE (WM_SIZEPARENT, OnSizeParent)
282// Global help commands
283END_MESSAGE_MAP ()
284
285RulerBar::RulerBar (BOOL b3DExt)
286 : m_leftmargin (IDB_RULER_BLOCK, IDB_RULER_UP, m_indent)
287 , m_indent (IDB_RULER_DOWN)
288 , m_rightmargin (IDB_RULER_UP)
289 , m_tabItem (IDB_RULER_TAB)
290{
291 m_bDeferInProgress = FALSE;
292 m_leftmargin.SetRuler (this);
293 m_indent.SetRuler (this);
294 m_rightmargin.SetRuler (this);
295
296 // all of the tab stops share handles
297 for (int i = 0; i < MAX_TAB_STOPS; ++i) {
298 m_pTabItems[i].m_hbm = m_tabItem.m_hbm;
299 m_pTabItems[i].m_hbmMask = m_tabItem.m_hbmMask;
300 m_pTabItems[i].m_size = m_tabItem.m_size;
301 }
302
303 m_unit.m_nTPU = 0;
304 m_nScroll = 0;
305
306 LOGFONT m_lf;
307 {
308 HFONT hFont = (HFONT)GetStockObject (DEFAULT_GUI_FONT);
309 if (hFont == NULL)
310 hFont = (HFONT)GetStockObject (ANSI_VAR_FONT);
311 VERIFY (GetObject (hFont, sizeof (LOGFONT), &m_lf));
312 }
313
314 LOGFONT lf;
315 memcpy (&lf, &m_lf, sizeof (LOGFONT));
316 lf.lfHeight = -8;
317 lf.lfWidth = 0;
318 VERIFY (fnt.CreateFontIndirect (&lf));
319
320 m_nTabs = 0;
321 m_leftmargin.SetVertPos (9);
322 m_indent.SetVertPos (-1);
323 m_rightmargin.SetVertPos (9);
324
325 // m_cxLeftBorder = 0;
326 m_cxLeftBorder = Led_CvtScreenPixelsFromTWIPSH (kLedItViewLHSMargin);
327 m_bDraw3DExt = b3DExt;
328
329 m_cyTopBorder = 4;
330 m_cyBottomBorder = 6;
331
332 m_pSelItem = NULL;
333
334 CWindowDC screenDC (NULL);
335 m_logx = screenDC.GetDeviceCaps (LOGPIXELSX);
336
337 CreateGDIObjects ();
338}
339
340RulerBar::~RulerBar ()
341{
342 // set handles to NULL to avoid deleting twice
343 for (int i = 0; i < MAX_TAB_STOPS; ++i) {
344 m_pTabItems[i].m_hbm = NULL;
345 m_pTabItems[i].m_hbmMask = NULL;
346 }
347}
348
349void RulerBar::CreateGDIObjects ()
350{
351 penFocusLine.DeleteObject ();
352 penBtnHighLight.DeleteObject ();
353 penBtnShadow.DeleteObject ();
354 penWindowFrame.DeleteObject ();
355 penBtnText.DeleteObject ();
356 penBtnFace.DeleteObject ();
357 penWindowText.DeleteObject ();
358 penWindow.DeleteObject ();
359 brushWindow.DeleteObject ();
360 brushBtnFace.DeleteObject ();
361
362 penFocusLine.CreatePen (PS_DOT, 1, GetSysColor (COLOR_WINDOWTEXT));
363 penBtnHighLight.CreatePen (PS_SOLID, 0, GetSysColor (COLOR_BTNHIGHLIGHT));
364 penBtnShadow.CreatePen (PS_SOLID, 0, GetSysColor (COLOR_BTNSHADOW));
365 penWindowFrame.CreatePen (PS_SOLID, 0, GetSysColor (COLOR_WINDOWFRAME));
366 penBtnText.CreatePen (PS_SOLID, 0, GetSysColor (COLOR_BTNTEXT));
367 penBtnFace.CreatePen (PS_SOLID, 0, GetSysColor (COLOR_BTNFACE));
368 penWindowText.CreatePen (PS_SOLID, 0, GetSysColor (COLOR_WINDOWTEXT));
369 penWindow.CreatePen (PS_SOLID, 0, GetSysColor (COLOR_WINDOW));
370 brushWindow.CreateSolidBrush (GetSysColor (COLOR_WINDOW));
371 brushBtnFace.CreateSolidBrush (GetSysColor (COLOR_BTNFACE));
372}
373
374LedItView* RulerBar::GetView ()
375{
376 ASSERT (GetParent () != NULL);
377 return dynamic_cast<LedItView*> (((CFrameWnd*)GetParent ())->GetActiveView ());
378}
379
380void RulerBar::OnUpdateCmdUI (CFrameWnd* /*pTarget*/, BOOL /*bDisableIfNoHndler*/)
381{
382 ASSERT_VALID (this);
383 //Get the page size and see if changed -- from document
384 //get margins and tabs and see if changed -- from view
385 if (m_pSelItem == NULL) { // only update if not in middle of dragging
386 LedItView* pView = GetView ();
387
388 //TMPHACK
389 CSize fakePaperSize (0x2fd0, 0x3de0);
390 CRect fakeMargins (0x5a0, 0x05a0, 0x708, 0x708);
391 Update (fakePaperSize, fakeMargins);
392 //PARAFORMAT fakeParaFormat;
393 //memset (&fakeParaFormat. 0, sizeof (fakeParaFormat));
394 //Update(fakeParaFormat);
395 Update (pView->GetParaFormatSelection ());
396
397#if 0
398// must add ability to get this crap from Led!!!
399
400 ASSERT(pView != NULL);
401 Update(pView->GetPaperSize(), pView->GetMargins());
402 Update(pView->GetParaFormatSelection());
403 CRect rect;
404 pView->GetRichEditCtrl().GetRect(&rect);
405 CPoint pt = rect.TopLeft();
406 pView->ClientToScreen(&pt);
407 ScreenToClient(&pt);
408 if (m_cxLeftBorder != pt.x) {
409 m_cxLeftBorder = pt.x;
410 Invalidate();
411 }
412 int nScroll = pView->GetScrollPos(SB_HORZ);
413 if (nScroll != m_nScroll) {
414 m_nScroll = nScroll;
415 Invalidate();
416 }
417#endif
418 }
419}
420
421CSize RulerBar::GetBaseUnits ()
422{
423 ASSERT (fnt.GetSafeHandle () != NULL);
424 CWindowDC screenDC (NULL);
425 CFont* pFont = screenDC.SelectObject (&fnt);
426 TEXTMETRIC tm;
427 VERIFY (screenDC.GetTextMetrics (&tm) == TRUE);
428 screenDC.SelectObject (pFont);
429 return CSize (tm.tmAveCharWidth, tm.tmHeight);
430}
431
432BOOL RulerBar::Create (CWnd* pParentWnd, DWORD dwStyle, UINT nID)
433{
434 ASSERT_VALID (pParentWnd); // must have a parent
435
436 dwStyle |= WS_CLIPSIBLINGS;
437 // force WS_CLIPSIBLINGS (avoids SetWindowPos bugs)
438 m_dwStyle = (dwStyle & CBRS_ALL);
439
440 // create the HWND
441 CRect rect;
442 rect.SetRectEmpty ();
443 LPCTSTR lpszClass = AfxRegisterWndClass (0, ::LoadCursor (NULL, IDC_ARROW), (HBRUSH)(COLOR_BTNFACE + 1), NULL);
444
445 if (!CWnd::Create (lpszClass, NULL, dwStyle, rect, pParentWnd, nID))
446 return FALSE;
447 // NOTE: Parent must resize itself for control bar to be resized
448
449 int i;
450 int nMax = 100;
451 for (i = 0; i < MAX_TAB_STOPS; ++i) {
452 m_pTabItems[i].SetRuler (this);
453 m_pTabItems[i].SetVertPos (8);
454 m_pTabItems[i].SetHorzPosTwips (0);
455 m_pTabItems[i].SetBounds (0, nMax);
456 }
457 return TRUE;
458}
459
460CSize RulerBar::CalcFixedLayout (BOOL bStretch, BOOL bHorz)
461{
462 ASSERT (bHorz);
463 CSize m_size = CControlBar::CalcFixedLayout (bStretch, bHorz);
464 CRect rectSize;
465 rectSize.SetRectEmpty ();
466 CalcInsideRect (rectSize, bHorz); // will be negative size
467 m_size.cy = RULERBARHEIGHT - rectSize.Height ();
468 return m_size;
469}
470
471void RulerBar::Update (const IncrementalParagraphInfo& pf)
472{
473 if (pf.GetTabStopList_Valid ()) {
474 StandardTabStopList tabStops = pf.GetTabStopList ();
475 DistanceType tabSoFar = 0;
476 Require (tabStops.fTabStops.size () <= MAX_TAB_STOPS);
477 size_t i = 0;
478 for (; i < tabStops.fTabStops.size (); ++i) {
479 tabSoFar += tabStops.fTabStops[i];
480 m_pTabItems[i].SetHorzPosTwips (tabSoFar);
481 }
482 for (; i < MAX_TAB_STOPS; ++i) {
483 m_pTabItems[i].SetHorzPosTwips (0);
484 }
485 }
486
487 if (pf.GetMargins_Valid ()) {
488 m_leftmargin.SetHorzPosTwips (pf.GetLeftMargin ());
489 m_rightmargin.SetHorzPosTwips (pf.GetRightMargin ());
490 if (pf.GetFirstIndent_Valid ()) {
491 m_indent.SetHorzPosTwips (pf.GetLeftMargin () + pf.GetFirstIndent ());
492 }
493 }
494}
495
496void RulerBar::Update (CSize sizePaper, const CRect& rectMargins)
497{
498 if ((sizePaper != m_sizePaper) || (rectMargins != m_rectMargin)) {
499 m_sizePaper = sizePaper;
500 m_rectMargin = rectMargins;
501 Invalidate ();
502 }
503
504 if (m_unit.GetTPU () != StandardUnits::GetCurrentUnits ().GetTPU ()) {
505 m_unit = StandardUnits::GetCurrentUnits ();
506 Invalidate ();
507 }
508#if 0
509 // MUST ADD ABILITY TO GET THSI CRAP FROM LED??
510
511 if (m_unit.m_nTPU != theApp.GetTPU()) {
512 m_unit = theApp.GetUnit();
513 Invalidate();
514 }
515#endif
516}
517
518void RulerBar::FillInParaFormat (IncrementalParagraphInfo& pf)
519{
521 //we don't set the justification - just the tabstops (AND SOON THE START/RIGHT INDENT).
522 SortTabs ();
523 int nPos = 0;
524 vector<TWIPS> v;
525 int soFar = 0;
526 for (size_t i = 0; i < MAX_TAB_STOPS; ++i) {
527 // get rid of zeroes and multiples
528 // i.e. if we have 0,0,0,1,2,3,4,4,5
529 // we will get tabs at 1,2,3,4,5
530 if (nPos != m_pTabItems[i].GetHorzPosTwips ()) {
531 nPos = m_pTabItems[i].GetHorzPosTwips ();
532 Assert (nPos > soFar);
533 //pf.rgxTabs[pf.cTabCount++] = nPos;
534 v.push_back (TWIPS (nPos - soFar));
535 soFar = nPos;
536 }
537 }
538 pf.SetTabStopList (StandardTabStopList{v});
539
540 pf.SetMargins (TWIPS{m_leftmargin.GetHorzPosTwips ()}, TWIPS{m_rightmargin.GetHorzPosTwips ()});
541 pf.SetFirstIndent (TWIPS{m_indent.GetHorzPosTwips () - m_leftmargin.GetHorzPosTwips ()});
542}
543
544// simple bubble sort is adequate for small number of tabs
545void RulerBar::SortTabs ()
546{
547 int i, j, nPos;
548 for (i = 0; i < MAX_TAB_STOPS - 1; ++i) {
549 for (j = i + 1; j < MAX_TAB_STOPS; ++j) {
550 if (m_pTabItems[j].GetHorzPosTwips () < m_pTabItems[i].GetHorzPosTwips ()) {
551 nPos = m_pTabItems[j].GetHorzPosTwips ();
552 m_pTabItems[j].SetHorzPosTwips (m_pTabItems[i].GetHorzPosTwips ());
553 m_pTabItems[i].SetHorzPosTwips (nPos);
554 }
555 }
556 }
557}
558
559void RulerBar::DoPaint (CDC* pDC)
560{
561 CControlBar::DoPaint (pDC); // CControlBar::DoPaint -- draws border
562 if (m_unit.m_nTPU != 0) {
563 pDC->SaveDC ();
564 // offset coordinate system
565 CPoint pointOffset (0, 0);
566 RulerToClient (pointOffset);
567 pDC->SetViewportOrg (pointOffset);
568
569 DrawFace (*pDC);
570 DrawTickMarks (*pDC);
571
572 DrawTabs (*pDC);
573 m_leftmargin.Draw (*pDC);
574 m_indent.Draw (*pDC);
575 m_rightmargin.Draw (*pDC);
576
577 pDC->RestoreDC (-1);
578 }
579 // Do not call CControlBar::OnPaint() for painting messages
580}
581
582void RulerBar::DrawTabs (CDC& dc)
583{
584 int i;
585 int nPos = 0;
586 for (i = 0; i < MAX_TAB_STOPS; ++i) {
587 if (m_pTabItems[i].GetHorzPosTwips () > nPos)
588 nPos = (m_pTabItems[i].GetHorzPosTwips ());
589 m_pTabItems[i].Draw (dc);
590 }
591 int nPageWidth = PrintWidth ();
592 nPos = nPos - nPos % 720 + 720;
593 dc.SelectObject (&penBtnShadow);
594 for (; nPos < nPageWidth; nPos += 720) {
595 int nx = XTwipsToRuler (nPos);
596 dc.MoveTo (nx, HEIGHT - 1);
597 dc.LineTo (nx, HEIGHT + 1);
598 }
599}
600
601void RulerBar::DrawFace (CDC& dc)
602{
603 int nPageWidth = XTwipsToRuler (PrintWidth ());
604 int nPageEdge = XTwipsToRuler (PrintWidth () + m_rectMargin.right);
605
606 dc.SaveDC ();
607
608 dc.SelectObject (&penBtnShadow);
609 dc.MoveTo (0, 0);
610 dc.LineTo (nPageEdge - 1, 0);
611 dc.LineTo (nPageEdge - 1, HEIGHT - 2);
612 dc.LineTo (nPageWidth - 1, HEIGHT - 2);
613 dc.LineTo (nPageWidth - 1, 1);
614 dc.LineTo (nPageWidth, 1);
615 dc.LineTo (nPageWidth, HEIGHT - 2);
616
617 dc.SelectObject (&penBtnHighLight);
618 dc.MoveTo (nPageWidth, HEIGHT - 1);
619 dc.LineTo (nPageEdge, HEIGHT - 1);
620 dc.MoveTo (nPageWidth + 1, HEIGHT - 3);
621 dc.LineTo (nPageWidth + 1, 1);
622 dc.LineTo (nPageEdge - 1, 1);
623
624 dc.SelectObject (&penWindow);
625 dc.MoveTo (0, HEIGHT - 1);
626 dc.LineTo (nPageWidth, HEIGHT - 1);
627
628 dc.SelectObject (&penBtnFace);
629 dc.MoveTo (1, HEIGHT - 2);
630 dc.LineTo (nPageWidth - 1, HEIGHT - 2);
631
632 dc.SelectObject (&penWindowFrame);
633 dc.MoveTo (0, HEIGHT - 2);
634 dc.LineTo (0, 1);
635 dc.LineTo (nPageWidth - 1, 1);
636
637 dc.FillRect (CRect (1, 2, nPageWidth - 1, HEIGHT - 2), &brushWindow);
638 dc.FillRect (CRect (nPageWidth + 2, 2, nPageEdge - 1, HEIGHT - 2), &brushBtnFace);
639
640 CRect rcClient;
641 GetClientRect (&rcClient);
642 ClientToRuler (rcClient);
643 rcClient.top = HEIGHT;
644 rcClient.bottom = HEIGHT + 2;
645 dc.FillRect (rcClient, &brushBtnFace);
646
647 CRect rectFill (rcClient.left, HEIGHT + 4, rcClient.right, HEIGHT + 9);
648 dc.FillRect (rectFill, &brushWindow);
649
650 if (m_bDraw3DExt) { // draws the 3D extension into the view
651 dc.SelectObject (&penBtnShadow);
652 dc.MoveTo (rcClient.left, HEIGHT + 8);
653 dc.LineTo (rcClient.left, HEIGHT + 2);
654 dc.LineTo (rcClient.right - 1, HEIGHT + 2);
655
656 dc.SelectObject (&penWindowFrame);
657 dc.MoveTo (rcClient.left + 1, HEIGHT + 8);
658 dc.LineTo (rcClient.left + 1, HEIGHT + 3);
659 dc.LineTo (rcClient.right - 2, HEIGHT + 3);
660
661 dc.SelectObject (&penBtnHighLight);
662 dc.MoveTo (rcClient.right - 1, HEIGHT + 2);
663 dc.LineTo (rcClient.right - 1, HEIGHT + 8);
664
665 dc.SelectObject (&penBtnFace);
666 dc.MoveTo (rcClient.right - 2, HEIGHT + 3);
667 dc.LineTo (rcClient.right - 2, HEIGHT + 8);
668 }
669 else {
670 dc.SelectObject (&penBtnShadow);
671 dc.MoveTo (rcClient.left, HEIGHT + 2);
672 dc.LineTo (rcClient.right, HEIGHT + 2);
673
674 dc.SelectObject (&penWindowFrame);
675 dc.MoveTo (rcClient.left, HEIGHT + 3);
676 dc.LineTo (rcClient.right, HEIGHT + 3);
677 }
678
679 dc.RestoreDC (-1);
680}
681
682void RulerBar::DrawTickMarks (CDC& dc)
683{
684 dc.SaveDC ();
685
686 dc.SelectObject (&penWindowText);
687 dc.SelectObject (&fnt);
688 dc.SetTextColor (GetSysColor (COLOR_WINDOWTEXT));
689 dc.SetBkMode (TRANSPARENT);
690
691 DrawDiv (dc, m_unit.m_nSmallDiv, m_unit.m_nLargeDiv, 2);
692 DrawDiv (dc, m_unit.m_nMediumDiv, m_unit.m_nLargeDiv, 5);
693 DrawNumbers (dc, m_unit.m_nLargeDiv, m_unit.m_nTPU);
694
695 dc.RestoreDC (-1);
696}
697
698void RulerBar::DrawNumbers (CDC& dc, int nInc, int nTPU)
699{
700 int nPageWidth = PrintWidth ();
701 int nPageEdge = nPageWidth + m_rectMargin.right;
702 TCHAR buf[10];
703
704 int nTwips, nPixel, nLen;
705
706 for (nTwips = nInc; nTwips < nPageEdge; nTwips += nInc) {
707 if (nTwips == nPageWidth)
708 continue;
709 nPixel = XTwipsToRuler (nTwips);
710 wsprintf (buf, _T("%d"), nTwips / nTPU);
711 nLen = lstrlen (buf);
712 CSize sz = dc.GetTextExtent (buf, nLen);
713 dc.ExtTextOut (nPixel - sz.cx / 2, HEIGHT / 2 - sz.cy / 2, 0, NULL, buf, nLen, NULL);
714 }
715}
716
717void RulerBar::DrawDiv (CDC& dc, int nInc, int nLargeDiv, int nLength)
718{
719 int nPageWidth = PrintWidth ();
720 int nPageEdge = nPageWidth + m_rectMargin.right;
721
722 int nTwips, nPixel;
723
724 for (nTwips = nInc; nTwips < nPageEdge; nTwips += nInc) {
725 if (nTwips == nPageWidth || nTwips % nLargeDiv == 0)
726 continue;
727 nPixel = XTwipsToRuler (nTwips);
728 dc.MoveTo (nPixel, HEIGHT / 2 - nLength / 2);
729 dc.LineTo (nPixel, HEIGHT / 2 - nLength / 2 + nLength);
730 }
731}
732
733void RulerBar::OnLButtonDown (UINT nFlags, CPoint point)
734{
735 CPoint pt = point;
736 ClientToRuler (pt);
737
738 m_pSelItem = NULL;
739 if (m_leftmargin.HitTestPix (pt))
740 m_pSelItem = &m_leftmargin;
741 else if (m_indent.HitTestPix (pt))
742 m_pSelItem = &m_indent;
743 else if (m_rightmargin.HitTestPix (pt))
744 m_pSelItem = &m_rightmargin;
745 else
746 m_pSelItem = GetHitTabPix (pt);
747 if (m_pSelItem == NULL)
748 m_pSelItem = GetFreeTab ();
749 if (m_pSelItem == NULL)
750 return;
751 SetCapture ();
752
753 m_pSelItem->SetTrack (TRUE);
754 SetMarginBounds ();
755 OnMouseMove (nFlags, point);
756}
757
758void RulerBar::SetMarginBounds ()
759{
760 m_leftmargin.SetBounds (0, m_rightmargin.GetHorzPosTwips ());
761 m_indent.SetBounds (0, m_rightmargin.GetHorzPosTwips ());
762
763 int nMin = (m_leftmargin.GetHorzPosTwips () > m_indent.GetHorzPosTwips ()) ? m_leftmargin.GetHorzPosTwips () : m_indent.GetHorzPosTwips ();
764 int nMax = PrintWidth () + m_rectMargin.right;
765 m_rightmargin.SetBounds (nMin, nMax);
766
767 // tabs can go from zero to the right page edge
768 for (int i = 0; i < MAX_TAB_STOPS; ++i)
769 m_pTabItems[i].SetBounds (0, nMax);
770}
771
772RulerItem* RulerBar::GetFreeTab ()
773{
774 int i;
775 for (i = 0; i < MAX_TAB_STOPS; ++i) {
776 if (m_pTabItems[i].GetHorzPosTwips () == 0)
777 return &m_pTabItems[i];
778 }
779 return NULL;
780}
781
782CTabRulerItem* RulerBar::GetHitTabPix (CPoint point)
783{
784 int i;
785 for (i = 0; i < MAX_TAB_STOPS; ++i) {
786 if (m_pTabItems[i].HitTestPix (point))
787 return &m_pTabItems[i];
788 }
789 return NULL;
790}
791
792void RulerBar::OnLButtonUp (UINT nFlags, CPoint point)
793{
794 if (::GetCapture () != m_hWnd)
795 return;
796 OnMouseMove (nFlags, point);
797 m_pSelItem->SetTrack (FALSE);
798 ReleaseCapture ();
799 LedItView* pView = GetView ();
800 IncrementalParagraphInfo pf = pView->GetParaFormatSelection ();
801 FillInParaFormat (pf);
802 pView->SetParaFormatSelection (pf);
803
804 m_pSelItem = NULL;
805}
806
807void RulerBar::OnMouseMove (UINT nFlags, CPoint point)
808{
809 CControlBar::OnMouseMove (nFlags, point);
810 // use ::GetCapture to avoid creating temporaries
811 if (::GetCapture () != m_hWnd)
812 return;
813 ASSERT (m_pSelItem != NULL);
814 CRect rc (0, 0, XTwipsToRuler (PrintWidth () + m_rectMargin.right), HEIGHT);
815 RulerToClient (rc);
816 BOOL bOnRuler = rc.PtInRect (point);
817
818 // snap to minimum movement
819 point.x = XClientToTwips (point.x);
820 point.x += m_unit.m_nMinMove / 2;
821 point.x -= point.x % m_unit.m_nMinMove;
822
823 m_pSelItem->TrackHorzPosTwips (point.x, bOnRuler);
824 UpdateWindow ();
825}
826
827void RulerBar::OnSysColorChange ()
828{
829 CControlBar::OnSysColorChange ();
830 CreateGDIObjects ();
831 Invalidate ();
832}
833
834void RulerBar::OnWindowPosChanging (WINDOWPOS FAR* lpwndpos)
835{
836 CControlBar::OnWindowPosChanging (lpwndpos);
837 CRect rect;
838 GetClientRect (rect);
839 int minx = min (rect.Width (), lpwndpos->cx);
840 int maxx = max (rect.Width (), lpwndpos->cx);
841 rect.SetRect (minx - 2, rect.bottom - 6, minx, rect.bottom);
842 InvalidateRect (rect);
843 rect.SetRect (maxx - 2, rect.bottom - 6, maxx, rect.bottom);
844 InvalidateRect (rect);
845}
846
847void RulerBar::OnShowWindow (BOOL bShow, UINT nStatus)
848{
849 CControlBar::OnShowWindow (bShow, nStatus);
850 m_bDeferInProgress = FALSE;
851}
852
853void RulerBar::OnWindowPosChanged (WINDOWPOS FAR* lpwndpos)
854{
855 CControlBar::OnWindowPosChanged (lpwndpos);
856 m_bDeferInProgress = FALSE;
857}
858
859LRESULT RulerBar::OnSizeParent (WPARAM wParam, LPARAM lParam)
860{
861 BOOL bVis = GetStyle () & WS_VISIBLE;
862 if ((bVis && (m_nStateFlags & delayHide)) || (!bVis && (m_nStateFlags & delayShow))) {
863 m_bDeferInProgress = TRUE;
864 }
865 return CControlBar::OnSizeParent (wParam, lParam);
866}