mirror of
https://github.com/reactos/reactos.git
synced 2025-08-02 05:45:50 +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
|
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));
|
HPEN oldPen = (HPEN) SelectObject(hdc, CreatePen(PS_SOLID, 1, color));
|
||||||
HBRUSH oldBrush = (HBRUSH) SelectObject(hdc, CreateSolidBrush(color));
|
HBRUSH oldBrush = (HBRUSH) SelectObject(hdc, CreateSolidBrush(color));
|
||||||
LONG a, b;
|
|
||||||
b = max(1, max(labs(x2 - x1), labs(y2 - y1)));
|
if (thickness <= 1)
|
||||||
switch (style)
|
|
||||||
{
|
{
|
||||||
case 0:
|
Line(hdc, x1, y1, x2, y2, color, thickness);
|
||||||
for(a = 0; a <= b; a++)
|
}
|
||||||
Ellipse(hdc, (x1 * (b - a) + x2 * a) / b - 3, (y1 * (b - a) + y2 * a) / b - 3,
|
else
|
||||||
(x1 * (b - a) + x2 * a) / b + 4, (y1 * (b - a) + y2 * a) / b + 4);
|
{
|
||||||
break;
|
LONG a, b = max(1, max(labs(x2 - x1), labs(y2 - y1)));
|
||||||
case 1:
|
switch ((BrushStyle)style)
|
||||||
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:
|
|
||||||
{
|
{
|
||||||
POINT offsTop[] = {{3, -3}, {2, -2}, {0, 0},
|
case BrushStyleRound:
|
||||||
{-4, -4}, {-2, -2}, {-1, 0}};
|
for (a = 0; a <= b; a++)
|
||||||
POINT offsBtm[] = {{-3, 3}, {-2, 2}, {-1, 1},
|
{
|
||||||
{3, 3}, {2, 2}, {0, 1}};
|
Ellipse(hdc,
|
||||||
LONG idx = style - 6;
|
(x1 * (b - a) + x2 * a) / b - (thickness / 2),
|
||||||
POINT pts[4];
|
(y1 * (b - a) + y2 * a) / b - (thickness / 2),
|
||||||
pts[0].x = x1 + offsTop[idx].x;
|
(x1 * (b - a) + x2 * a) / b + (thickness / 2),
|
||||||
pts[0].y = y1 + offsTop[idx].y;
|
(y1 * (b - a) + y2 * a) / b + (thickness / 2));
|
||||||
pts[1].x = x1 + offsBtm[idx].x;
|
}
|
||||||
pts[1].y = y1 + offsBtm[idx].y;
|
break;
|
||||||
pts[2].x = x2 + offsBtm[idx].x;
|
|
||||||
pts[2].y = y2 + offsBtm[idx].y;
|
case BrushStyleSquare:
|
||||||
pts[3].x = x2 + offsTop[idx].x;
|
for (a = 0; a <= b; a++)
|
||||||
pts[3].y = y2 + offsTop[idx].y;
|
{
|
||||||
Polygon(hdc, pts, 4);
|
Rectangle(hdc,
|
||||||
break;
|
(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));
|
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 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);
|
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
|
void draw(BOOL bLeftButton, LONG x, LONG y) override
|
||||||
{
|
{
|
||||||
COLORREF rgb = bLeftButton ? m_fg : m_bg;
|
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
|
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);
|
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)
|
VOID CToolSettingsWindow::drawBrush(HDC hdc, LPCRECT prc)
|
||||||
{
|
{
|
||||||
RECT rects[12];
|
RECT rects[12];
|
||||||
getBrushRects(rects, prc);
|
getBrushRects(rects, prc);
|
||||||
|
|
||||||
::FillRect(hdc, &rects[toolsModel.GetBrushStyle()], (HBRUSH)(COLOR_HIGHLIGHT + 1));
|
|
||||||
|
|
||||||
for (INT i = 0; i < 12; i++)
|
for (INT i = 0; i < 12; i++)
|
||||||
{
|
{
|
||||||
RECT rcItem = rects[i];
|
RECT rcItem = rects[i];
|
||||||
INT x = (rcItem.left + rcItem.right) / 2, y = (rcItem.top + rcItem.bottom) / 2;
|
INT x = (rcItem.left + rcItem.right) / 2, y = (rcItem.top + rcItem.bottom) / 2;
|
||||||
|
|
||||||
INT iColor;
|
INT iColor;
|
||||||
if (i == toolsModel.GetBrushStyle())
|
const BrushStyleAndWidth& data = c_BrushPresets[i];
|
||||||
|
if (data.width == toolsModel.GetBrushWidth() && data.style == toolsModel.GetBrushStyle())
|
||||||
|
{
|
||||||
iColor = COLOR_HIGHLIGHTTEXT;
|
iColor = COLOR_HIGHLIGHTTEXT;
|
||||||
|
::FillRect(hdc, &rcItem, (HBRUSH)(COLOR_HIGHLIGHT + 1));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
iColor = COLOR_WINDOWTEXT;
|
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:
|
case TOOL_BRUSH:
|
||||||
iItem = getBrushRects(rects, &rect1, &pt);
|
iItem = getBrushRects(rects, &rect1, &pt);
|
||||||
if (iItem != -1)
|
if (iItem != -1)
|
||||||
toolsModel.SetBrushStyle(iItem);
|
{
|
||||||
|
const BrushStyleAndWidth& data = c_BrushPresets[iItem];
|
||||||
|
toolsModel.SetBrushStyle(data.style);
|
||||||
|
toolsModel.SetBrushWidth(data.width);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case TOOL_AIRBRUSH:
|
case TOOL_AIRBRUSH:
|
||||||
iItem = getAirBrushRects(rects, &rect1, &pt);
|
iItem = getAirBrushRects(rects, &rect1, &pt);
|
||||||
|
|
|
@ -14,8 +14,9 @@ ToolsModel toolsModel;
|
||||||
ToolsModel::ToolsModel()
|
ToolsModel::ToolsModel()
|
||||||
{
|
{
|
||||||
m_lineWidth = m_penWidth = 1;
|
m_lineWidth = m_penWidth = 1;
|
||||||
|
m_brushWidth = 4;
|
||||||
m_shapeStyle = 0;
|
m_shapeStyle = 0;
|
||||||
m_brushStyle = 0;
|
m_brushStyle = BrushStyleRound;
|
||||||
m_oldActiveTool = m_activeTool = TOOL_PEN;
|
m_oldActiveTool = m_activeTool = TOOL_PEN;
|
||||||
m_airBrushWidth = 5;
|
m_airBrushWidth = 5;
|
||||||
m_rubberRadius = 4;
|
m_rubberRadius = 4;
|
||||||
|
@ -68,6 +69,18 @@ void ToolsModel::SetPenWidth(INT nPenWidth)
|
||||||
imageModel.NotifyImageChanged();
|
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)
|
void ToolsModel::MakeLineThickerOrThinner(BOOL bThinner)
|
||||||
{
|
{
|
||||||
INT thickness = GetLineWidth();
|
INT thickness = GetLineWidth();
|
||||||
|
@ -80,6 +93,12 @@ void ToolsModel::MakePenThickerOrThinner(BOOL bThinner)
|
||||||
SetPenWidth(bThinner ? max(1, thickness - 1) : (thickness + 1));
|
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
|
int ToolsModel::GetShapeStyle() const
|
||||||
{
|
{
|
||||||
return m_shapeStyle;
|
return m_shapeStyle;
|
||||||
|
@ -91,12 +110,12 @@ void ToolsModel::SetShapeStyle(int nShapeStyle)
|
||||||
NotifyToolSettingsChanged();
|
NotifyToolSettingsChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
int ToolsModel::GetBrushStyle() const
|
BrushStyle ToolsModel::GetBrushStyle() const
|
||||||
{
|
{
|
||||||
return m_brushStyle;
|
return m_brushStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToolsModel::SetBrushStyle(int nBrushStyle)
|
void ToolsModel::SetBrushStyle(BrushStyle nBrushStyle)
|
||||||
{
|
{
|
||||||
m_brushStyle = nBrushStyle;
|
m_brushStyle = nBrushStyle;
|
||||||
NotifyToolSettingsChanged();
|
NotifyToolSettingsChanged();
|
||||||
|
|
|
@ -28,6 +28,14 @@ enum TOOLTYPE
|
||||||
TOOL_MAX = TOOL_RRECT,
|
TOOL_MAX = TOOL_RRECT,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum BrushStyle
|
||||||
|
{
|
||||||
|
BrushStyleRound,
|
||||||
|
BrushStyleSquare,
|
||||||
|
BrushStyleForeSlash,
|
||||||
|
BrushStyleBackSlash,
|
||||||
|
};
|
||||||
|
|
||||||
/* CLASSES **********************************************************/
|
/* CLASSES **********************************************************/
|
||||||
|
|
||||||
struct ToolBase
|
struct ToolBase
|
||||||
|
@ -68,8 +76,9 @@ class ToolsModel
|
||||||
private:
|
private:
|
||||||
int m_lineWidth;
|
int m_lineWidth;
|
||||||
INT m_penWidth;
|
INT m_penWidth;
|
||||||
|
INT m_brushWidth;
|
||||||
int m_shapeStyle;
|
int m_shapeStyle;
|
||||||
int m_brushStyle;
|
BrushStyle m_brushStyle;
|
||||||
TOOLTYPE m_activeTool;
|
TOOLTYPE m_activeTool;
|
||||||
TOOLTYPE m_oldActiveTool;
|
TOOLTYPE m_oldActiveTool;
|
||||||
int m_airBrushWidth;
|
int m_airBrushWidth;
|
||||||
|
@ -97,17 +106,27 @@ public:
|
||||||
|
|
||||||
int GetShapeStyle() const;
|
int GetShapeStyle() const;
|
||||||
void SetShapeStyle(int nShapeStyle);
|
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 GetActiveTool() const;
|
||||||
TOOLTYPE GetOldActiveTool() const;
|
TOOLTYPE GetOldActiveTool() const;
|
||||||
void SetActiveTool(TOOLTYPE nActiveTool);
|
void SetActiveTool(TOOLTYPE nActiveTool);
|
||||||
|
|
||||||
int GetAirBrushWidth() const;
|
int GetAirBrushWidth() const;
|
||||||
void SetAirBrushWidth(int nAirBrushWidth);
|
void SetAirBrushWidth(int nAirBrushWidth);
|
||||||
|
|
||||||
int GetRubberRadius() const;
|
int GetRubberRadius() const;
|
||||||
void SetRubberRadius(int nRubberRadius);
|
void SetRubberRadius(int nRubberRadius);
|
||||||
|
|
||||||
BOOL IsBackgroundTransparent() const;
|
BOOL IsBackgroundTransparent() const;
|
||||||
void SetBackgroundTransparent(BOOL bTransparent);
|
void SetBackgroundTransparent(BOOL bTransparent);
|
||||||
|
|
||||||
int GetZoom() const;
|
int GetZoom() const;
|
||||||
void SetZoom(int nZoom);
|
void SetZoom(int nZoom);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue