mirror of
https://github.com/reactos/reactos.git
synced 2025-02-20 15:35:04 +00:00
[MSPAINT] Larger/smaller brush nib on Ctrl+Plus/Minus (#5739)
- Introduce the concept of "brush width" to the tools model. - Enable changing the brush width by Ctrl+Plus/Minus key combination in TOOL_BRUSH. - Re-define brush styles. CORE-19094
This commit is contained in:
parent
c84b5007d0
commit
8a4787b384
6 changed files with 132 additions and 76 deletions
|
@ -165,73 +165,66 @@ Airbrush(HDC hdc, LONG x, LONG y, COLORREF color, LONG r)
|
|||
}
|
||||
|
||||
void
|
||||
Brush(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2, COLORREF color, LONG style)
|
||||
Brush(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2, COLORREF color, LONG style, INT thickness)
|
||||
{
|
||||
HPEN oldPen = (HPEN) SelectObject(hdc, CreatePen(PS_SOLID, 1, color));
|
||||
HBRUSH oldBrush = (HBRUSH) SelectObject(hdc, CreateSolidBrush(color));
|
||||
LONG a, b;
|
||||
b = max(1, max(labs(x2 - x1), labs(y2 - y1)));
|
||||
switch (style)
|
||||
|
||||
if (thickness <= 1)
|
||||
{
|
||||
case 0:
|
||||
for(a = 0; a <= b; a++)
|
||||
Ellipse(hdc, (x1 * (b - a) + x2 * a) / b - 3, (y1 * (b - a) + y2 * a) / b - 3,
|
||||
(x1 * (b - a) + x2 * a) / b + 4, (y1 * (b - a) + y2 * a) / b + 4);
|
||||
break;
|
||||
case 1:
|
||||
for(a = 0; a <= b; a++)
|
||||
Ellipse(hdc,
|
||||
(x1 * (b - a) + x2 * a) / b - 2,
|
||||
(y1 * (b - a) + y2 * a) / b - 2,
|
||||
(x1 * (b - a) + x2 * a) / b + 2,
|
||||
(y1 * (b - a) + y2 * a) / b + 2);
|
||||
break;
|
||||
case 2:
|
||||
MoveToEx(hdc, x1, y1, NULL);
|
||||
LineTo(hdc, x2, y2);
|
||||
::SetPixelV(hdc, x2, y2, color);
|
||||
break;
|
||||
case 3:
|
||||
for(a = 0; a <= b; a++)
|
||||
Rectangle(hdc,
|
||||
(x1 * (b - a) + x2 * a) / b - 4,
|
||||
(y1 * (b - a) + y2 * a) / b - 4,
|
||||
(x1 * (b - a) + x2 * a) / b + 4,
|
||||
(y1 * (b - a) + y2 * a) / b + 4);
|
||||
break;
|
||||
case 4:
|
||||
for(a = 0; a <= b; a++)
|
||||
Rectangle(hdc, (x1 * (b - a) + x2 * a) / b - 2, (y1 * (b - a) + y2 * a) / b - 2,
|
||||
(x1 * (b - a) + x2 * a) / b + 3, (y1 * (b - a) + y2 * a) / b + 3);
|
||||
break;
|
||||
case 5:
|
||||
for(a = 0; a <= b; a++)
|
||||
Rectangle(hdc, (x1 * (b - a) + x2 * a) / b - 1, (y1 * (b - a) + y2 * a) / b - 1,
|
||||
(x1 * (b - a) + x2 * a) / b + 1, (y1 * (b - a) + y2 * a) / b + 1);
|
||||
break;
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
Line(hdc, x1, y1, x2, y2, color, thickness);
|
||||
}
|
||||
else
|
||||
{
|
||||
LONG a, b = max(1, max(labs(x2 - x1), labs(y2 - y1)));
|
||||
switch ((BrushStyle)style)
|
||||
{
|
||||
POINT offsTop[] = {{3, -3}, {2, -2}, {0, 0},
|
||||
{-4, -4}, {-2, -2}, {-1, 0}};
|
||||
POINT offsBtm[] = {{-3, 3}, {-2, 2}, {-1, 1},
|
||||
{3, 3}, {2, 2}, {0, 1}};
|
||||
LONG idx = style - 6;
|
||||
POINT pts[4];
|
||||
pts[0].x = x1 + offsTop[idx].x;
|
||||
pts[0].y = y1 + offsTop[idx].y;
|
||||
pts[1].x = x1 + offsBtm[idx].x;
|
||||
pts[1].y = y1 + offsBtm[idx].y;
|
||||
pts[2].x = x2 + offsBtm[idx].x;
|
||||
pts[2].y = y2 + offsBtm[idx].y;
|
||||
pts[3].x = x2 + offsTop[idx].x;
|
||||
pts[3].y = y2 + offsTop[idx].y;
|
||||
Polygon(hdc, pts, 4);
|
||||
break;
|
||||
case BrushStyleRound:
|
||||
for (a = 0; a <= b; a++)
|
||||
{
|
||||
Ellipse(hdc,
|
||||
(x1 * (b - a) + x2 * a) / b - (thickness / 2),
|
||||
(y1 * (b - a) + y2 * a) / b - (thickness / 2),
|
||||
(x1 * (b - a) + x2 * a) / b + (thickness / 2),
|
||||
(y1 * (b - a) + y2 * a) / b + (thickness / 2));
|
||||
}
|
||||
break;
|
||||
|
||||
case BrushStyleSquare:
|
||||
for (a = 0; a <= b; a++)
|
||||
{
|
||||
Rectangle(hdc,
|
||||
(x1 * (b - a) + x2 * a) / b - (thickness / 2),
|
||||
(y1 * (b - a) + y2 * a) / b - (thickness / 2),
|
||||
(x1 * (b - a) + x2 * a) / b + (thickness / 2),
|
||||
(y1 * (b - a) + y2 * a) / b + (thickness / 2));
|
||||
}
|
||||
break;
|
||||
|
||||
case BrushStyleForeSlash:
|
||||
case BrushStyleBackSlash:
|
||||
{
|
||||
POINT offsetTop, offsetBottom;
|
||||
if ((BrushStyle)style == BrushStyleForeSlash)
|
||||
{
|
||||
offsetTop = { (thickness - 1) / 2, -(thickness - 1) / 2 };
|
||||
offsetBottom = { -thickness / 2, thickness / 2 };
|
||||
}
|
||||
else
|
||||
{
|
||||
offsetTop = { -thickness / 2, -thickness / 2 };
|
||||
offsetBottom = { (thickness - 1) / 2, (thickness - 1) / 2 };
|
||||
}
|
||||
POINT points[4] =
|
||||
{
|
||||
{ x1 + offsetTop.x, y1 + offsetTop.y },
|
||||
{ x1 + offsetBottom.x, y1 + offsetBottom.y },
|
||||
{ x2 + offsetBottom.x, y2 + offsetBottom.y },
|
||||
{ x2 + offsetTop.x, y2 + offsetTop.y },
|
||||
};
|
||||
Polygon(hdc, points, _countof(points));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
DeleteObject(SelectObject(hdc, oldBrush));
|
||||
|
|
|
@ -27,7 +27,7 @@ void Replace(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2, COLORREF fg, COLORREF
|
|||
|
||||
void Airbrush(HDC hdc, LONG x, LONG y, COLORREF color, LONG r);
|
||||
|
||||
void Brush(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2, COLORREF color, LONG style);
|
||||
void Brush(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2, COLORREF color, LONG style, INT thickness);
|
||||
|
||||
void RectSel(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2);
|
||||
|
||||
|
|
|
@ -609,12 +609,13 @@ struct BrushTool : SmoothDrawTool
|
|||
void draw(BOOL bLeftButton, LONG x, LONG y) override
|
||||
{
|
||||
COLORREF rgb = bLeftButton ? m_fg : m_bg;
|
||||
Brush(m_hdc, g_ptEnd.x, g_ptEnd.y, x, y, rgb, toolsModel.GetBrushStyle());
|
||||
Brush(m_hdc, g_ptEnd.x, g_ptEnd.y, x, y, rgb, toolsModel.GetBrushStyle(),
|
||||
toolsModel.GetBrushWidth());
|
||||
}
|
||||
|
||||
void OnSpecialTweak(BOOL bMinus) override
|
||||
{
|
||||
// TODO:
|
||||
toolsModel.MakeBrushThickerOrThinner(bMinus);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -112,23 +112,43 @@ static inline INT getBrushRects(RECT rects[12], LPCRECT prc, LPPOINT ppt = NULL)
|
|||
return getSplitRects(rects, 3, 4, prc, ppt);
|
||||
}
|
||||
|
||||
struct BrushStyleAndWidth
|
||||
{
|
||||
BrushStyle style;
|
||||
INT width;
|
||||
};
|
||||
|
||||
static const BrushStyleAndWidth c_BrushPresets[] =
|
||||
{
|
||||
{ BrushStyleRound, 7 }, { BrushStyleRound, 4 }, { BrushStyleRound, 1 },
|
||||
{ BrushStyleSquare, 8 }, { BrushStyleSquare, 5 }, { BrushStyleSquare, 2 },
|
||||
{ BrushStyleForeSlash, 8 }, { BrushStyleForeSlash, 5 }, { BrushStyleForeSlash, 2 },
|
||||
{ BrushStyleBackSlash, 8 }, { BrushStyleBackSlash, 5 }, { BrushStyleBackSlash, 2 },
|
||||
};
|
||||
|
||||
VOID CToolSettingsWindow::drawBrush(HDC hdc, LPCRECT prc)
|
||||
{
|
||||
RECT rects[12];
|
||||
getBrushRects(rects, prc);
|
||||
|
||||
::FillRect(hdc, &rects[toolsModel.GetBrushStyle()], (HBRUSH)(COLOR_HIGHLIGHT + 1));
|
||||
|
||||
for (INT i = 0; i < 12; i++)
|
||||
{
|
||||
RECT rcItem = rects[i];
|
||||
INT x = (rcItem.left + rcItem.right) / 2, y = (rcItem.top + rcItem.bottom) / 2;
|
||||
|
||||
INT iColor;
|
||||
if (i == toolsModel.GetBrushStyle())
|
||||
const BrushStyleAndWidth& data = c_BrushPresets[i];
|
||||
if (data.width == toolsModel.GetBrushWidth() && data.style == toolsModel.GetBrushStyle())
|
||||
{
|
||||
iColor = COLOR_HIGHLIGHTTEXT;
|
||||
::FillRect(hdc, &rcItem, (HBRUSH)(COLOR_HIGHLIGHT + 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
iColor = COLOR_WINDOWTEXT;
|
||||
Brush(hdc, x, y, x, y, ::GetSysColor(iColor), i);
|
||||
}
|
||||
|
||||
Brush(hdc, x, y, x, y, ::GetSysColor(iColor), data.style, data.width);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -383,7 +403,11 @@ LRESULT CToolSettingsWindow::OnLButtonDown(UINT nMsg, WPARAM wParam, LPARAM lPar
|
|||
case TOOL_BRUSH:
|
||||
iItem = getBrushRects(rects, &rect1, &pt);
|
||||
if (iItem != -1)
|
||||
toolsModel.SetBrushStyle(iItem);
|
||||
{
|
||||
const BrushStyleAndWidth& data = c_BrushPresets[iItem];
|
||||
toolsModel.SetBrushStyle(data.style);
|
||||
toolsModel.SetBrushWidth(data.width);
|
||||
}
|
||||
break;
|
||||
case TOOL_AIRBRUSH:
|
||||
iItem = getAirBrushRects(rects, &rect1, &pt);
|
||||
|
|
|
@ -14,8 +14,9 @@ ToolsModel toolsModel;
|
|||
ToolsModel::ToolsModel()
|
||||
{
|
||||
m_lineWidth = m_penWidth = 1;
|
||||
m_brushWidth = 4;
|
||||
m_shapeStyle = 0;
|
||||
m_brushStyle = 0;
|
||||
m_brushStyle = BrushStyleRound;
|
||||
m_oldActiveTool = m_activeTool = TOOL_PEN;
|
||||
m_airBrushWidth = 5;
|
||||
m_rubberRadius = 4;
|
||||
|
@ -68,6 +69,18 @@ void ToolsModel::SetPenWidth(INT nPenWidth)
|
|||
imageModel.NotifyImageChanged();
|
||||
}
|
||||
|
||||
INT ToolsModel::GetBrushWidth() const
|
||||
{
|
||||
return m_brushWidth;
|
||||
}
|
||||
|
||||
void ToolsModel::SetBrushWidth(INT nBrushWidth)
|
||||
{
|
||||
m_brushWidth = nBrushWidth;
|
||||
NotifyToolSettingsChanged();
|
||||
imageModel.NotifyImageChanged();
|
||||
}
|
||||
|
||||
void ToolsModel::MakeLineThickerOrThinner(BOOL bThinner)
|
||||
{
|
||||
INT thickness = GetLineWidth();
|
||||
|
@ -80,6 +93,12 @@ void ToolsModel::MakePenThickerOrThinner(BOOL bThinner)
|
|||
SetPenWidth(bThinner ? max(1, thickness - 1) : (thickness + 1));
|
||||
}
|
||||
|
||||
void ToolsModel::MakeBrushThickerOrThinner(BOOL bThinner)
|
||||
{
|
||||
INT thickness = GetBrushWidth();
|
||||
SetBrushWidth(bThinner ? max(1, thickness - 1) : (thickness + 1));
|
||||
}
|
||||
|
||||
int ToolsModel::GetShapeStyle() const
|
||||
{
|
||||
return m_shapeStyle;
|
||||
|
@ -91,12 +110,12 @@ void ToolsModel::SetShapeStyle(int nShapeStyle)
|
|||
NotifyToolSettingsChanged();
|
||||
}
|
||||
|
||||
int ToolsModel::GetBrushStyle() const
|
||||
BrushStyle ToolsModel::GetBrushStyle() const
|
||||
{
|
||||
return m_brushStyle;
|
||||
}
|
||||
|
||||
void ToolsModel::SetBrushStyle(int nBrushStyle)
|
||||
void ToolsModel::SetBrushStyle(BrushStyle nBrushStyle)
|
||||
{
|
||||
m_brushStyle = nBrushStyle;
|
||||
NotifyToolSettingsChanged();
|
||||
|
|
|
@ -28,6 +28,14 @@ enum TOOLTYPE
|
|||
TOOL_MAX = TOOL_RRECT,
|
||||
};
|
||||
|
||||
enum BrushStyle
|
||||
{
|
||||
BrushStyleRound,
|
||||
BrushStyleSquare,
|
||||
BrushStyleForeSlash,
|
||||
BrushStyleBackSlash,
|
||||
};
|
||||
|
||||
/* CLASSES **********************************************************/
|
||||
|
||||
struct ToolBase
|
||||
|
@ -68,8 +76,9 @@ class ToolsModel
|
|||
private:
|
||||
int m_lineWidth;
|
||||
INT m_penWidth;
|
||||
INT m_brushWidth;
|
||||
int m_shapeStyle;
|
||||
int m_brushStyle;
|
||||
BrushStyle m_brushStyle;
|
||||
TOOLTYPE m_activeTool;
|
||||
TOOLTYPE m_oldActiveTool;
|
||||
int m_airBrushWidth;
|
||||
|
@ -97,17 +106,27 @@ public:
|
|||
|
||||
int GetShapeStyle() const;
|
||||
void SetShapeStyle(int nShapeStyle);
|
||||
int GetBrushStyle() const;
|
||||
void SetBrushStyle(int nBrushStyle);
|
||||
|
||||
INT GetBrushWidth() const;
|
||||
void SetBrushWidth(INT nBrushWidth);
|
||||
void MakeBrushThickerOrThinner(BOOL bThinner);
|
||||
|
||||
BrushStyle GetBrushStyle() const;
|
||||
void SetBrushStyle(BrushStyle nBrushStyle);
|
||||
|
||||
TOOLTYPE GetActiveTool() const;
|
||||
TOOLTYPE GetOldActiveTool() const;
|
||||
void SetActiveTool(TOOLTYPE nActiveTool);
|
||||
|
||||
int GetAirBrushWidth() const;
|
||||
void SetAirBrushWidth(int nAirBrushWidth);
|
||||
|
||||
int GetRubberRadius() const;
|
||||
void SetRubberRadius(int nRubberRadius);
|
||||
|
||||
BOOL IsBackgroundTransparent() const;
|
||||
void SetBackgroundTransparent(BOOL bTransparent);
|
||||
|
||||
int GetZoom() const;
|
||||
void SetZoom(int nZoom);
|
||||
|
||||
|
|
Loading…
Reference in a new issue