root / trunk / win / Colorlst.cpp

Revision 723, 10.6 kB (checked in by Leo, 7 months ago)

Rewrote messaging system.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1#include "lc_global.h"
2#include "leocad.h"
3#include "ColorLst.h"
4#include "lc_colors.h"
5#include "lc_message.h"
6#include "lc_application.h"
7
8#ifdef _DEBUG
9#define new DEBUG_NEW
10#undef THIS_FILE
11static char THIS_FILE[] = __FILE__;
12#endif
13
14#define CXOFFSET 8  // Defined pitch of trapezoid slant.
15#define CXMARGIN 2  // Left/Right text margin.
16#define CYMARGIN 1  // Top/Bottom text margin.
17#define CYBORDER 1  // Top border thickness.
18
19// Given the boundint rect, compute trapezoid region.
20void CColorTab::GetTrapezoid(const CRect& rc, CPoint* pts) const
21{
22    pts[0] = CPoint(rc.left, rc.bottom);
23    pts[1] = CPoint(rc.left + CXOFFSET, rc.top);
24    pts[2] = CPoint(rc.right - CXOFFSET-1, rc.top);
25    pts[3] = CPoint(rc.right - 1, rc.bottom);
26}
27
28void CColorTab::Draw(CDC& dc, CFont& Font, BOOL Selected, BOOL Focus)
29{
30    // Tab drawing code based on an article by Paul DiLascia.
31    COLORREF bgColor = GetSysColor(Selected ? COLOR_WINDOW : COLOR_3DFACE);
32    COLORREF fgColor = GetSysColor(Selected ? COLOR_WINDOWTEXT : COLOR_BTNTEXT);
33
34    CBrush brush(bgColor);
35    dc.SetBkColor(bgColor);
36    dc.SetTextColor(fgColor);
37
38    CPen blackPen(PS_SOLID, 1, RGB(0, 0, 0));
39    CPen shadowPen(PS_SOLID, 1, GetSysColor(COLOR_3DSHADOW));
40
41    // Fill trapezoid.
42    CPoint pts[4];
43    CRect rc = m_Rect;
44    GetTrapezoid(rc, pts);
45    CPen* pOldPen = dc.SelectObject(&blackPen);
46    dc.FillRgn(&m_Rgn, &brush);
47
48    // Draw edges. This is requires two corrections:
49    // 1) Trapezoid dimensions don't include the right and bottom edges,
50    // so must use one pixel less on bottom (cybottom)
51    // 2) the endpoint of LineTo is not included when drawing the line, so
52    // must add one pixel (cytop)
53    pts[0].y--;
54    dc.MoveTo(pts[0]);            // bottom left
55    dc.LineTo(pts[1]);            // upper left
56    dc.SelectObject(&shadowPen);  // top line is shadow color
57    dc.MoveTo(pts[1]);            // line is inside trapezoid top
58    dc.LineTo(pts[2]);
59    dc.SelectObject(&blackPen);   // upstroke is black
60    dc.LineTo(pts[3]);            // y-1 to include endpoint
61    if (!Selected)
62    {
63        // If not highlighted, upstroke has a 3D shadow, one pixel inside.
64        pts[2].x--;  // offset left one pixel
65        pts[3].x--;  // ...ditto
66        dc.SelectObject(&shadowPen);
67        dc.MoveTo(pts[2]);
68        dc.LineTo(pts[3]);
69    }
70    dc.SelectObject(pOldPen);
71
72    // draw text
73    rc.DeflateRect(CXOFFSET + CXMARGIN, CYMARGIN);
74    CFont* OldFont = dc.SelectObject(&Font);
75    dc.DrawText(m_Text, &rc, DT_CENTER|DT_VCENTER|DT_SINGLELINE);
76    dc.SelectObject(OldFont);
77
78    if (Focus && Selected)
79        dc.DrawFocusRect(rc);
80}
81
82BEGIN_MESSAGE_MAP(CColorList, CWnd)
83    //{{AFX_MSG_MAP(CColorList)
84    ON_WM_PAINT()
85    ON_WM_LBUTTONDOWN()
86    ON_WM_SIZE()
87    ON_WM_KEYDOWN()
88    ON_WM_SETFOCUS()
89    ON_WM_KILLFOCUS()
90    ON_WM_GETDLGCODE()
91    ON_WM_SETCURSOR()
92    ON_WM_CREATE()
93    //}}AFX_MSG_MAP
94END_MESSAGE_MAP()
95
96CColorList::CColorList()
97{
98    m_Tabs.Add(new CColorTab("test"));
99    m_Tabs.Add(new CColorTab("test 2"));
100
101    m_Colors.SetSize(lcNumUserColors);
102    for (int i = 0; i < lcNumUserColors; i++)
103    {
104        CColorEntry& Entry = m_Colors[i];
105        Entry.Name = lcColorList[i].Name;
106        Entry.Color = LC_COLOR_RGB(i);
107        Entry.Index = i;
108    }
109
110    m_CurTab = 0;
111    m_CurColor = 0;
112    m_ColorFocus = true;
113}
114
115CColorList::~CColorList()
116{
117    for (int i = 0; i < m_Tabs.GetSize(); i++)
118        delete (CColorTab*)m_Tabs[i];
119    m_Tabs.RemoveAll();
120}
121
122BOOL CColorList::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID)
123{
124    ASSERT(pParentWnd && ::IsWindow(pParentWnd->GetSafeHwnd()));
125
126    // Get the class name and create the window
127    CString ClassName = AfxRegisterWndClass(CS_CLASSDC|CS_SAVEBITS|CS_HREDRAW|CS_VREDRAW, 0, CreateSolidBrush(GetSysColor(COLOR_BTNFACE)), 0);
128
129    if (!CWnd::Create(ClassName, _T(""), dwStyle, rect, pParentWnd, nID, NULL))
130        return FALSE;
131
132    // Initialize fonts.
133    LOGFONT lf;
134    memset(&lf, 0, sizeof(lf));
135    lf.lfHeight = GetSystemMetrics(SM_CYHSCROLL)-CYMARGIN;
136    lf.lfWeight = FW_NORMAL;
137    lf.lfCharSet = DEFAULT_CHARSET;
138    _tcscpy(lf.lfFaceName, _T("Arial"));
139    m_NormalFont.CreateFontIndirect(&lf);
140
141    lf.lfWeight = FW_BOLD;
142    m_SelectedFont.CreateFontIndirect(&lf);
143
144    UpdateLayout();
145
146    return TRUE;
147}
148
149int CColorList::OnCreate(LPCREATESTRUCT lpCreateStruct)
150{
151    if (CWnd::OnCreate(lpCreateStruct) == -1)
152        return -1;
153
154    m_ToolTip.Create(this);
155
156    return 0;
157}
158
159BOOL CColorList::PreTranslateMessage(MSG* pMsg)
160{
161    if (m_ToolTip.m_hWnd)
162        m_ToolTip.RelayEvent(pMsg);
163
164    return CWnd::PreTranslateMessage(pMsg);
165}
166
167void CColorList::OnPaint()
168{
169    CPaintDC dc(this);
170
171    CColorTab* CurTab = NULL;
172    BOOL Focus = (GetFocus() == this);
173
174    // Draw all the normal tabs.
175    for (int i = 0; i < m_Tabs.GetSize(); i++)
176    {
177        CColorTab* Tab = (CColorTab*)m_Tabs[i];
178
179        if (i == m_CurTab)
180            CurTab = Tab;
181        else
182            Tab->Draw(dc, m_NormalFont, FALSE, Focus && !m_ColorFocus);
183    }
184
185    // Draw selected tab last so it will be "on top" of the others.
186    if (CurTab)
187        CurTab->Draw(dc, m_SelectedFont, TRUE, Focus && !m_ColorFocus);
188
189    // Draw the colors.
190    CPen BlackPen;
191    BlackPen.CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
192    CPen* OldPen = (CPen*)dc.SelectObject(&BlackPen);
193
194    for (int i = 0; i < m_Colors.GetSize(); i++)
195    {
196        CBrush brush;
197
198        if (LC_COLOR_TRANSLUCENT(m_Colors[i].Index))
199        {
200            WORD CheckerBits[8] = { 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33 };
201
202            // Use the bit pattern to create a bitmap.
203            CBitmap bm;
204            bm.CreateBitmap(8, 8, 1, 1, CheckerBits);
205
206            // Create a pattern brush from the bitmap.
207            brush.CreatePatternBrush(&bm);
208            dc.SetTextColor(m_Colors[i].Color);
209            dc.SetBkColor(RGB(255, 255, 255));
210        }
211        else
212        {
213            brush.CreateSolidBrush(m_Colors[i].Color);
214        }
215
216        CBrush* OldBrush = (CBrush*)dc.SelectObject(&brush);
217
218        CRect rc = m_Colors[i].Rect;
219        rc.bottom++;
220        rc.right++;
221        dc.Rectangle(rc);
222
223        dc.SelectObject(OldBrush);
224    }
225
226    CBrush* OldBrush = (CBrush*)dc.SelectObject(GetStockObject(NULL_BRUSH));
227
228    COLORREF cr = m_Colors[m_CurColor].Color;
229    CPen BorderPen;
230    BorderPen.CreatePen(PS_SOLID, 1, RGB(255-GetRValue(cr), 255-GetGValue(cr), 255-GetBValue(cr)));
231    dc.SelectObject(&BorderPen);
232
233    CRect rc = m_Colors[m_CurColor].Rect;
234    rc.OffsetRect(1, 1);
235    rc.bottom--;
236    rc.right--;
237    dc.Rectangle(rc);
238
239    dc.SelectObject(OldPen);
240    dc.SelectObject(OldBrush);
241
242    if (Focus && m_ColorFocus)
243    {
244        rc.DeflateRect(2, 2);
245        dc.DrawFocusRect(rc);
246    }
247}
248
249void CColorList::UpdateLayout()
250{
251    CClientDC dc(this);
252
253    CFont* OldFont = dc.SelectObject(&m_SelectedFont);
254    int x = 0;
255
256    for (int i = 0; i < m_Tabs.GetSize(); i++)
257    {
258        CColorTab* Tab = (CColorTab*)m_Tabs[i];
259
260        // Calculate desired text rectangle.
261        CRect& rc = Tab->m_Rect;
262        rc.SetRectEmpty();
263        dc.DrawText(Tab->m_Text, &rc, DT_CALCRECT);
264        rc.right += 2 * CXOFFSET + 3 * CXMARGIN;
265        rc.bottom = rc.top + GetSystemMetrics(SM_CYHSCROLL);
266        rc += CPoint(x,0);
267
268        // Create trapezoid region.
269        CPoint pts[4];
270        Tab->GetTrapezoid(rc, pts);
271        Tab->m_Rgn.DeleteObject();
272        Tab->m_Rgn.CreatePolygonRgn(pts, 4, WINDING);
273
274        x += rc.Width() - CXOFFSET;
275    }
276
277    dc.SelectObject(OldFont);
278
279    CRect rc;
280    GetClientRect(&rc);
281    rc.top = ((CColorTab*)m_Tabs[0])->m_Rect.bottom;
282
283    m_ColorRows = 6;
284    m_ColorCols = 13;
285
286    int CellWidth = rc.Width() / m_ColorCols;
287    int CellHeight = rc.Height() / m_ColorRows;
288
289    for (int i = 0; i < lcNumUserColors; i++)
290        m_ToolTip.DelTool(this, i+1);
291
292    for (int i = 0; i < m_ColorRows; i++)
293    {
294        for (int j = 0; j < m_ColorCols; j++)
295        {
296            CRect cell(0, 0, CellWidth, CellHeight);
297            cell.OffsetRect(j * CellWidth + rc.left, i * CellHeight + rc.top);
298
299            int Index = i*m_ColorCols + j;
300            m_Colors[Index].Rect = cell;
301            m_ToolTip.AddTool(this, lcColorList[Index].Name, cell, Index+1);
302        }
303    }
304}
305
306void CColorList::OnLButtonDown(UINT Flags, CPoint pt)
307{
308    CWnd::OnLButtonDown(Flags, pt);
309    SetFocus();
310
311    CRect rc;
312    GetClientRect(&rc);
313
314    if (!rc.PtInRect(pt))
315        return;
316
317    for (int i = 0; i < m_Tabs.GetSize(); i++)
318    {
319        CColorTab* TabPtr = (CColorTab*)m_Tabs[i];
320
321        if (TabPtr->m_Rgn.PtInRegion(pt))
322        {
323            SelectTab(i);
324            return;
325        }
326    }
327
328    for (int i = 0; i < m_Colors.GetSize(); i++)
329    {
330        if (m_Colors[i].Rect.PtInRect(pt))
331        {
332            SelectColor(i);
333            return;
334        }
335    }
336}
337
338void CColorList::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
339{
340    int Row = m_CurColor / m_ColorCols;
341    int Col = m_CurColor % m_ColorCols;
342
343    switch (nChar)
344    {
345        case VK_UP:
346            if (m_ColorFocus)
347            {
348                if (Row > 0)
349                {
350                    Row--;
351
352                    SelectColor(Row * m_ColorCols + Col);
353                }
354                else
355                    SelectTab(m_CurTab);
356            }
357            break;
358
359        case VK_DOWN:
360            if (m_ColorFocus)
361            {
362                if (Row < m_ColorRows - 1)
363                    Row++;
364
365                SelectColor(Row * m_ColorCols + Col);
366            }
367            else
368                SelectColor(m_CurColor);
369            break;
370
371        case VK_LEFT:
372            if (m_ColorFocus)
373            {
374                if (Col > 0)
375                    Col--;
376                else if (Row > 0)
377                {
378                    Row--;
379                    Col = m_ColorCols - 1;
380                }
381
382                SelectColor(Row * m_ColorCols + Col);
383            }
384            else
385            {
386                if (m_CurTab > 0)
387                    SelectTab(m_CurTab - 1);
388            }
389            break;
390
391        case VK_RIGHT:
392            if (m_ColorFocus)
393            {
394                if (Col < m_ColorCols - 1)
395                    Col++;
396                else if (Row < m_ColorRows - 1)
397                {
398                    Row++;
399                    Col = 0;
400                }
401
402                SelectColor(Row * m_ColorCols + Col);
403            }
404            else
405            {
406                if (m_CurTab < m_Tabs.GetSize() - 1)
407                    SelectTab(m_CurTab + 1);
408            }
409            break;
410    }
411
412    CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
413}
414
415BOOL CColorList::OnSetCursor(CWnd* inWnd, UINT inHitTest, UINT inMessage)
416{
417    HCURSOR Cursor = LoadCursor(NULL, IDC_ARROW);
418
419    if (Cursor)
420    {
421        SetCursor(Cursor);
422        return TRUE;
423    }
424
425    return CWnd::OnSetCursor(inWnd, inHitTest, inMessage);
426}
427
428UINT CColorList::OnGetDlgCode()
429{
430    return DLGC_WANTARROWS;
431}
432
433void CColorList::OnSetFocus(CWnd* pOldWnd)
434{
435    if (m_ColorFocus)
436        InvalidateRect(m_Colors[m_CurColor].Rect, TRUE);
437    else
438        InvalidateRect(((CColorTab*)m_Tabs[m_CurTab])->m_Rect, TRUE);
439
440    CWnd::OnSetFocus(pOldWnd);
441}
442
443void CColorList::OnKillFocus(CWnd* pNewWnd)
444{
445    if (m_ColorFocus)
446        InvalidateRect(m_Colors[m_CurColor].Rect, TRUE);
447    else
448        InvalidateRect(((CColorTab*)m_Tabs[m_CurTab])->m_Rect, TRUE);
449
450    CWnd::OnKillFocus(pNewWnd);
451}
452
453void CColorList::OnSize(UINT nType, int cx, int cy)
454{
455    CWnd::OnSize(nType, cx, cy);
456
457    UpdateLayout();
458}
459
460void CColorList::SelectTab(int Tab)
461{
462    if (Tab < 0 || Tab >= m_Tabs.GetSize())
463        return;
464
465    if (m_ColorFocus)
466    {
467        InvalidateRect(((CColorTab*)m_Tabs[Tab])->m_Rect, TRUE);
468        InvalidateRect(m_Colors[m_CurColor].Rect, TRUE);
469        m_ColorFocus = false;
470    }
471
472    if (Tab == m_CurTab)
473        return;
474
475    InvalidateRect(((CColorTab*)m_Tabs[m_CurTab])->m_Rect, TRUE);
476    InvalidateRect(((CColorTab*)m_Tabs[Tab])->m_Rect, TRUE);
477    m_CurTab = Tab;
478}
479
480void CColorList::SelectColor(int Color)
481{
482    if (Color < 0 || Color >= m_Colors.GetSize())
483        return;
484
485    if (!m_ColorFocus)
486    {
487        InvalidateRect(m_Colors[Color].Rect, TRUE);
488        InvalidateRect(((CColorTab*)m_Tabs[m_CurTab])->m_Rect, TRUE);
489        m_ColorFocus = true;
490    }
491
492    if (Color == m_CurColor)
493        return;
494
495    InvalidateRect(m_Colors[m_CurColor].Rect, TRUE);
496    InvalidateRect(m_Colors[Color].Rect, TRUE);
497    m_CurColor = Color;
498
499    g_App->m_SelectedColor = Color;
500    lcPostMessage(LC_MSG_COLOR_CHANGED, (void*)Color);
501}
Note: See TracBrowser for help on using the browser.