mirror of
https://github.com/leozide/leocad
synced 2024-12-30 22:23:45 +01:00
460 lines
9.6 KiB
C++
460 lines
9.6 KiB
C++
#include "lc_global.h"
|
|
#include "lc_colors.h"
|
|
#include "ColorLst.h"
|
|
#include "Piecebar.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
IMPLEMENT_DYNAMIC(CColorToolTipCtrl, CMFCToolTipCtrl)
|
|
|
|
BEGIN_MESSAGE_MAP(CColorToolTipCtrl, CMFCToolTipCtrl)
|
|
END_MESSAGE_MAP()
|
|
|
|
CSize CColorToolTipCtrl::GetIconSize()
|
|
{
|
|
return CSize(24, 24);
|
|
}
|
|
|
|
BOOL CColorToolTipCtrl::OnDrawIcon(CDC* pDC, CRect rectImage)
|
|
{
|
|
ASSERT_VALID(pDC);
|
|
|
|
CString Text;
|
|
GetWindowText(Text);
|
|
|
|
const char* Ptr = strrchr((const char*)Text, '(');
|
|
if (!Ptr)
|
|
return FALSE;
|
|
|
|
int Code;
|
|
if (sscanf(Ptr, "(%d)", &Code) != 1)
|
|
return FALSE;
|
|
|
|
lcColor* Color = &gColorList[lcGetColorIndex(Code)];
|
|
|
|
pDC->SetBkColor(RGB(Color->Value[0] * 255, Color->Value[1] * 255, Color->Value[2] * 255));
|
|
pDC->ExtTextOut(0, 0, ETO_OPAQUE, rectImage, NULL, 0, NULL);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BEGIN_MESSAGE_MAP(CColorList, CWnd)
|
|
//{{AFX_MSG_MAP(CColorList)
|
|
ON_WM_PAINT()
|
|
ON_WM_ERASEBKGND()
|
|
ON_WM_LBUTTONUP()
|
|
ON_WM_LBUTTONDOWN()
|
|
ON_WM_MOUSEMOVE()
|
|
ON_WM_SIZE()
|
|
ON_WM_KEYDOWN()
|
|
ON_WM_SETFOCUS()
|
|
ON_WM_KILLFOCUS()
|
|
ON_WM_GETDLGCODE()
|
|
ON_WM_SETCURSOR()
|
|
ON_WM_CREATE()
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
CColorList::CColorList()
|
|
{
|
|
mCurCell = 0;
|
|
mTracking = FALSE;
|
|
|
|
UpdateColors();
|
|
}
|
|
|
|
CColorList::~CColorList()
|
|
{
|
|
}
|
|
|
|
void CColorList::UpdateColors()
|
|
{
|
|
mCells.RemoveAll();
|
|
mGroups.RemoveAll();
|
|
mGroups.SetSize(LC_NUM_COLORGROUPS);
|
|
|
|
for (int GroupIdx = 0; GroupIdx < LC_NUM_COLORGROUPS; GroupIdx++)
|
|
{
|
|
lcColorGroup* Group = &gColorGroups[GroupIdx];
|
|
|
|
for (int ColorIdx = 0; ColorIdx < Group->Colors.GetSize(); ColorIdx++)
|
|
{
|
|
lcColor* Color = &gColorList[Group->Colors[ColorIdx]];
|
|
CColorListCell Cell;
|
|
|
|
Cell.Color = RGB(Color->Value[0] * 255, Color->Value[1] * 255, Color->Value[2] * 255);
|
|
Cell.ColorIndex = Group->Colors[ColorIdx];
|
|
|
|
mCells.Add(Cell);
|
|
}
|
|
}
|
|
|
|
mColumns = 14;
|
|
mRows = 0;
|
|
|
|
for (int GroupIdx = 0; GroupIdx < LC_NUM_COLORGROUPS; GroupIdx++)
|
|
mRows += (gColorGroups[GroupIdx].Colors.GetSize() + mColumns - 1) / mColumns;
|
|
}
|
|
|
|
void CColorList::UpdateLayout()
|
|
{
|
|
if (!IsWindow(m_hWnd))
|
|
return;
|
|
|
|
CRect ClientRect;
|
|
GetClientRect(&ClientRect);
|
|
|
|
CClientDC dc(this);
|
|
CFont* OldFont = dc.SelectObject(&afxGlobalData.fontRegular);
|
|
float TextHeight = 0.0f;
|
|
|
|
for (int GroupIdx = 0; GroupIdx < LC_NUM_COLORGROUPS; GroupIdx++)
|
|
{
|
|
lcColorGroup* Group = &gColorGroups[GroupIdx];
|
|
|
|
CSize TextSize = dc.GetTextExtent(Group->Name);
|
|
TextHeight += TextSize.cy;
|
|
}
|
|
|
|
float CellWidth = (float)ClientRect.Width() / (float)mColumns;
|
|
float CellHeight = ((float)ClientRect.Height() - TextHeight) / (float)mRows;
|
|
|
|
int CurCell = 0;
|
|
float CurY = 0.0f;
|
|
|
|
for (int GroupIdx = 0; GroupIdx < LC_NUM_COLORGROUPS; GroupIdx++)
|
|
{
|
|
lcColorGroup* Group = &gColorGroups[GroupIdx];
|
|
int CurColumn = 0;
|
|
|
|
CSize TextSize = dc.GetTextExtent(Group->Name);
|
|
mGroups[GroupIdx].Rect.SetRect(0, (int)CurY, ClientRect.Width(), (int)CurY + TextSize.cy);
|
|
CurY += TextSize.cy;
|
|
|
|
for (int ColorIdx = 0; ColorIdx < Group->Colors.GetSize(); ColorIdx++)
|
|
{
|
|
float Left = CurColumn * CellWidth;
|
|
float Right = (CurColumn + 1) * CellWidth;
|
|
float Top = CurY;
|
|
float Bottom = CurY + CellHeight;
|
|
|
|
CRect CellRect((int)Left, (int)Top, (int)Right, (int)Bottom);
|
|
|
|
mCells[CurCell].Rect = CellRect;
|
|
|
|
CString Text;
|
|
lcColor* Color = &gColorList[mCells[CurCell].ColorIndex];
|
|
Text.Format("%s (%d)", Color->Name, Color->Code);
|
|
mToolTip.AddTool(this, Text, CellRect, CurCell + 1);
|
|
|
|
CurColumn++;
|
|
if (CurColumn == mColumns)
|
|
{
|
|
CurColumn = 0;
|
|
CurY += CellHeight;
|
|
}
|
|
|
|
CurCell++;
|
|
}
|
|
|
|
if (CurColumn != 0)
|
|
CurY += CellHeight;
|
|
}
|
|
|
|
dc.SelectObject(OldFont);
|
|
}
|
|
|
|
void CColorList::SelectCell(int CellIdx)
|
|
{
|
|
if (CellIdx < 0 || CellIdx >= mCells.GetSize())
|
|
return;
|
|
|
|
if (CellIdx == mCurCell)
|
|
return;
|
|
|
|
InvalidateRect(mCells[mCurCell].Rect, TRUE);
|
|
InvalidateRect(mCells[CellIdx].Rect, TRUE);
|
|
mCurCell = CellIdx;
|
|
|
|
CPiecesBar* Bar = (CPiecesBar*)GetParent();
|
|
Bar->OnSelChangeColor();
|
|
}
|
|
|
|
BOOL CColorList::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID)
|
|
{
|
|
ASSERT(pParentWnd && ::IsWindow(pParentWnd->GetSafeHwnd()));
|
|
|
|
// Get the class name and create the window
|
|
CString ClassName = AfxRegisterWndClass(CS_CLASSDC|CS_SAVEBITS|CS_HREDRAW|CS_VREDRAW, 0, CreateSolidBrush(GetSysColor(COLOR_BTNFACE)), 0);
|
|
|
|
if (!CWnd::Create(ClassName, _T(""), dwStyle, rect, pParentWnd, nID, NULL))
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
int CColorList::OnCreate(LPCREATESTRUCT lpCreateStruct)
|
|
{
|
|
if (CWnd::OnCreate(lpCreateStruct) == -1)
|
|
return -1;
|
|
|
|
mToolTip.Create(this);
|
|
|
|
return 0;
|
|
}
|
|
|
|
BOOL CColorList::PreTranslateMessage(MSG* pMsg)
|
|
{
|
|
if (mToolTip.m_hWnd)
|
|
mToolTip.RelayEvent(pMsg);
|
|
|
|
return CWnd::PreTranslateMessage(pMsg);
|
|
}
|
|
|
|
void CColorList::OnPaint()
|
|
{
|
|
CPaintDC dc(this);
|
|
|
|
CDC MemDC;
|
|
CRect rect;
|
|
CBitmap bitmap, *pOldBitmap;
|
|
dc.GetClipBox(&rect);
|
|
MemDC.CreateCompatibleDC(&dc);
|
|
bitmap.CreateCompatibleBitmap(&dc, rect.Width(), rect.Height());
|
|
pOldBitmap = MemDC.SelectObject(&bitmap);
|
|
MemDC.SetWindowOrg(rect.left, rect.top);
|
|
Draw(MemDC);
|
|
dc.BitBlt(rect.left, rect.top, rect.Width(), rect.Height(), &MemDC, rect.left, rect.top, SRCCOPY);
|
|
MemDC.SelectObject(pOldBitmap);
|
|
}
|
|
|
|
BOOL CColorList::OnEraseBkgnd(CDC* pDC)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
void CColorList::Draw(CDC& dc)
|
|
{
|
|
CRect VisRect, ClipRect, rect;
|
|
GetClientRect(VisRect);
|
|
CBrush Back(GetSysColor(COLOR_WINDOW));
|
|
dc.FillRect(VisRect, &Back);
|
|
|
|
CFont* OldFont = dc.SelectObject(&afxGlobalData.fontRegular);
|
|
dc.SetBkMode(TRANSPARENT);
|
|
|
|
for (int GroupIdx = 0; GroupIdx < mGroups.GetSize(); GroupIdx++)
|
|
{
|
|
lcColorGroup* Group = &gColorGroups[GroupIdx];
|
|
CColorListGroup* ListGroup = &mGroups[GroupIdx];
|
|
|
|
dc.DrawText(Group->Name, ListGroup->Rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
|
|
}
|
|
|
|
dc.SelectObject(OldFont);
|
|
|
|
for (int CellIdx = 0; CellIdx < mCells.GetSize(); CellIdx++)
|
|
{
|
|
CBrush brush;
|
|
brush.CreateSolidBrush(mCells[CellIdx].Color);
|
|
|
|
CBrush* OldBrush = (CBrush*)dc.SelectObject(&brush);
|
|
|
|
CRect rc = mCells[CellIdx].Rect;
|
|
rc.bottom++;
|
|
rc.right++;
|
|
dc.Rectangle(rc);
|
|
|
|
dc.SelectObject(OldBrush);
|
|
}
|
|
|
|
if (mCurCell < mCells.GetSize())
|
|
{
|
|
CBrush* OldBrush = dc.SelectObject(CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH)));
|
|
|
|
COLORREF cr = mCells[mCurCell].Color;
|
|
CPen BorderPen;
|
|
BorderPen.CreatePen(PS_SOLID, 1, RGB(255-GetRValue(cr), 255-GetGValue(cr), 255-GetBValue(cr)));
|
|
CPen* OldPen = (CPen*)dc.SelectObject(&BorderPen);
|
|
|
|
CRect rc = mCells[mCurCell].Rect;
|
|
rc.OffsetRect(1, 1);
|
|
rc.bottom--;
|
|
rc.right--;
|
|
dc.Rectangle(rc);
|
|
|
|
if (GetFocus() == this)
|
|
{
|
|
rc.DeflateRect(2, 2);
|
|
dc.DrawFocusRect(rc);
|
|
}
|
|
|
|
dc.SelectObject(OldPen);
|
|
dc.SelectObject(OldBrush);
|
|
}
|
|
}
|
|
|
|
void CColorList::OnLButtonDown(UINT Flags, CPoint pt)
|
|
{
|
|
CWnd::OnLButtonDown(Flags, pt);
|
|
SetFocus();
|
|
|
|
CRect rc;
|
|
GetClientRect(&rc);
|
|
|
|
if (!rc.PtInRect(pt))
|
|
return;
|
|
|
|
for (int CellIdx = 0; CellIdx < mCells.GetSize(); CellIdx++)
|
|
{
|
|
if (!mCells[CellIdx].Rect.PtInRect(pt))
|
|
continue;
|
|
|
|
SelectCell(CellIdx);
|
|
|
|
SetCapture();
|
|
mMouseDown = pt;
|
|
mTracking = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
void CColorList::OnLButtonUp(UINT Flags, CPoint pt)
|
|
{
|
|
mTracking = FALSE;
|
|
ReleaseCapture();
|
|
|
|
CWnd::OnLButtonUp(Flags, pt);
|
|
}
|
|
|
|
void CColorList::OnMouseMove(UINT Flags, CPoint pt)
|
|
{
|
|
/*
|
|
if (m_Tracking && m_MouseDown != pt)
|
|
{
|
|
m_Tracking = FALSE;
|
|
ReleaseCapture();
|
|
lcGetActiveProject()->BeginColorDrop();
|
|
|
|
// Force a cursor update.
|
|
CFrameWnd* pFrame = (CFrameWnd*)AfxGetMainWnd();
|
|
CView* pView = pFrame->GetActiveView();
|
|
pView->PostMessage(WM_LC_SET_CURSOR, 0, 0);
|
|
}
|
|
*/
|
|
CWnd::OnMouseMove(Flags, pt);
|
|
}
|
|
|
|
void CColorList::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
|
|
{
|
|
if (nChar == VK_LEFT)
|
|
{
|
|
if (mCurCell > 0)
|
|
SelectCell(mCurCell - 1);
|
|
}
|
|
else if (nChar == VK_RIGHT)
|
|
{
|
|
if (mCurCell < mCells.GetSize() - 1)
|
|
SelectCell(mCurCell + 1);
|
|
}
|
|
else if (nChar == VK_UP || nChar == VK_DOWN)
|
|
{
|
|
if (mCurCell < 0 || mCurCell >= mCells.GetSize())
|
|
mCurCell = 0;
|
|
|
|
int CurGroup = 0;
|
|
int NumCells = 0;
|
|
|
|
for (CurGroup = 0; CurGroup < LC_NUM_COLORGROUPS; CurGroup++)
|
|
{
|
|
int NumColors = gColorGroups[CurGroup].Colors.GetSize();
|
|
|
|
if (mCurCell < NumCells + NumColors)
|
|
break;
|
|
|
|
NumCells += NumColors;
|
|
}
|
|
|
|
int Row = (mCurCell - NumCells) / mColumns;
|
|
int Column = (mCurCell - NumCells) % mColumns;
|
|
|
|
if (nChar == VK_UP)
|
|
{
|
|
if (Row > 0)
|
|
SelectCell(mCurCell - mColumns);
|
|
else if (CurGroup > 0)
|
|
{
|
|
int NumColors = gColorGroups[CurGroup - 1].Colors.GetSize();
|
|
int NumColumns = NumColors % mColumns;
|
|
|
|
if (NumColumns <= Column + 1)
|
|
SelectCell(mCurCell - NumColumns - mColumns);
|
|
else
|
|
SelectCell(mCurCell - NumColumns);
|
|
}
|
|
}
|
|
else if (nChar == VK_DOWN)
|
|
{
|
|
int NumColors = gColorGroups[CurGroup].Colors.GetSize();
|
|
|
|
if (mCurCell + mColumns < NumCells + NumColors)
|
|
SelectCell(mCurCell + mColumns);
|
|
else
|
|
{
|
|
int NumColumns = NumColors % mColumns;
|
|
|
|
if (NumColumns > Column)
|
|
SelectCell(mCurCell + NumColumns);
|
|
else
|
|
SelectCell(mCurCell + mColumns + NumColumns);
|
|
}
|
|
}
|
|
}
|
|
|
|
CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
|
|
}
|
|
|
|
BOOL CColorList::OnSetCursor(CWnd* inWnd, UINT inHitTest, UINT inMessage)
|
|
{
|
|
HCURSOR Cursor = LoadCursor(NULL, IDC_ARROW);
|
|
|
|
if (Cursor)
|
|
{
|
|
SetCursor(Cursor);
|
|
return TRUE;
|
|
}
|
|
|
|
return CWnd::OnSetCursor(inWnd, inHitTest, inMessage);
|
|
}
|
|
|
|
UINT CColorList::OnGetDlgCode()
|
|
{
|
|
return DLGC_WANTARROWS;
|
|
}
|
|
|
|
void CColorList::OnSetFocus(CWnd* pOldWnd)
|
|
{
|
|
if (mCurCell < mCells.GetSize())
|
|
InvalidateRect(mCells[mCurCell].Rect, TRUE);
|
|
|
|
CWnd::OnSetFocus(pOldWnd);
|
|
}
|
|
|
|
void CColorList::OnKillFocus(CWnd* pNewWnd)
|
|
{
|
|
if (mCurCell < mCells.GetSize())
|
|
InvalidateRect(mCells[mCurCell].Rect, TRUE);
|
|
|
|
CWnd::OnKillFocus(pNewWnd);
|
|
}
|
|
|
|
void CColorList::OnSize(UINT nType, int cx, int cy)
|
|
{
|
|
CWnd::OnSize(nType, cx, cy);
|
|
|
|
UpdateLayout();
|
|
}
|