Add "perfect circle brush" option (on by default), to allow using old circle brush

This commit is contained in:
jacob1 2020-02-03 00:20:46 -05:00
parent cb419cd85c
commit 1e23269dd4
10 changed files with 111 additions and 34 deletions

2
.gitignore vendored
View File

@ -56,6 +56,8 @@ Makefile.me
*.layout *.layout
*.config *.config
*.creator* *.creator*
*.cflags
*.cxxflags
*.files *.files
*.includes *.includes
config.log config.log

View File

@ -6,12 +6,16 @@
class EllipseBrush: public Brush class EllipseBrush: public Brush
{ {
bool perfectCircle;
public: public:
EllipseBrush(ui::Point size_): EllipseBrush(ui::Point size, bool perfectCircle = true):
Brush(size_) Brush(size)
{ {
SetRadius(size_); this->perfectCircle = perfectCircle;
SetRadius(size);
} }
void GenerateBitmap() override void GenerateBitmap() override
{ {
delete[] bitmap; delete[] bitmap;
@ -31,10 +35,16 @@ public:
int yTop = ry+1, yBottom, i; int yTop = ry+1, yBottom, i;
for (i = 0; i <= rx; i++) for (i = 0; i <= rx; i++)
{ {
while ( pow(i - rx, 2.0) * pow(ry - 0.5, 2.0) + if (perfectCircle)
pow(yTop - ry, 2.0) * pow(rx - 0.5, 2.0) <= {
pow(rx, 2.0) * pow(ry, 2.0)) while (pow(i - rx, 2.0) * pow(ry - 0.5, 2.0) + pow(yTop - ry, 2.0) * pow(rx - 0.5, 2.0) <= pow(rx, 2.0) * pow(ry, 2.0))
yTop++; yTop++;
}
else
{
while (pow(i - rx, 2.0) * pow(ry, 2.0) + pow(yTop - ry, 2.0) * pow(rx, 2.0) <= pow(rx, 2.0) * pow(ry, 2.0))
yTop++;
}
yBottom = 2*ry - yTop; yBottom = 2*ry - yTop;
for (int j = 0; j <= ry*2; j++) for (int j = 0; j <= ry*2; j++)
{ {

View File

@ -111,29 +111,8 @@ GameModel::GameModel():
BuildMenus(); BuildMenus();
//Set default brush palette perfectCircle = Client::Ref().GetPrefBool("PerfectCircleBrush", true);
brushList.push_back(new EllipseBrush(ui::Point(4, 4))); BuildBrushList();
brushList.push_back(new Brush(ui::Point(4, 4)));
brushList.push_back(new TriangleBrush(ui::Point(4, 4)));
//Load more from brushes folder
std::vector<ByteString> brushFiles = Client::Ref().DirectorySearch(BRUSH_DIR, "", ".ptb");
for (size_t i = 0; i < brushFiles.size(); i++)
{
std::vector<unsigned char> brushData = Client::Ref().ReadFile(brushFiles[i]);
if(!brushData.size())
{
std::cout << "Brushes: Skipping " << brushFiles[i] << ". Could not open" << std::endl;
continue;
}
size_t dimension = std::sqrt((float)brushData.size());
if (dimension * dimension != brushData.size())
{
std::cout << "Brushes: Skipping " << brushFiles[i] << ". Invalid bitmap size" << std::endl;
continue;
}
brushList.push_back(new BitmapBrush(brushData, ui::Point(dimension, dimension)));
}
//Set default decoration colour //Set default decoration colour
unsigned char colourR = std::min(Client::Ref().GetPrefInteger("Decoration.Red", 200), 255); unsigned char colourR = std::min(Client::Ref().GetPrefInteger("Decoration.Red", 200), 255);
@ -428,6 +407,45 @@ void GameModel::BuildFavoritesMenu()
notifyLastToolChanged(); notifyLastToolChanged();
} }
void GameModel::BuildBrushList()
{
bool hasStoredRadius = false;
ui::Point radius = ui::Point(0, 0);
if (brushList.size())
{
radius = brushList[currentBrush]->GetRadius();
hasStoredRadius = true;
}
brushList.clear();
brushList.push_back(new EllipseBrush(ui::Point(4, 4), perfectCircle));
brushList.push_back(new Brush(ui::Point(4, 4)));
brushList.push_back(new TriangleBrush(ui::Point(4, 4)));
//Load more from brushes folder
std::vector<ByteString> brushFiles = Client::Ref().DirectorySearch(BRUSH_DIR, "", ".ptb");
for (size_t i = 0; i < brushFiles.size(); i++)
{
std::vector<unsigned char> brushData = Client::Ref().ReadFile(brushFiles[i]);
if(!brushData.size())
{
std::cout << "Brushes: Skipping " << brushFiles[i] << ". Could not open" << std::endl;
continue;
}
size_t dimension = std::sqrt((float)brushData.size());
if (dimension * dimension != brushData.size())
{
std::cout << "Brushes: Skipping " << brushFiles[i] << ". Invalid bitmap size" << std::endl;
continue;
}
brushList.push_back(new BitmapBrush(brushData, ui::Point(dimension, dimension)));
}
if (hasStoredRadius && (size_t)currentBrush < brushList.size())
brushList[currentBrush]->SetRadius(radius);
notifyBrushChanged();
}
Tool *GameModel::GetToolFromIdentifier(ByteString const &identifier) Tool *GameModel::GetToolFromIdentifier(ByteString const &identifier)
{ {
for (auto *menu : menuList) for (auto *menu : menuList)
@ -1328,9 +1346,9 @@ bool GameModel::GetMouseClickRequired()
return mouseClickRequired; return mouseClickRequired;
} }
void GameModel::SetMouseClickRequired(bool mouseClickRequired_) void GameModel::SetMouseClickRequired(bool mouseClickRequired)
{ {
mouseClickRequired = mouseClickRequired_; this->mouseClickRequired = mouseClickRequired;
} }
bool GameModel::GetIncludePressure() bool GameModel::GetIncludePressure()
@ -1338,7 +1356,16 @@ bool GameModel::GetIncludePressure()
return includePressure; return includePressure;
} }
void GameModel::SetIncludePressure(bool includePressure_) void GameModel::SetIncludePressure(bool includePressure)
{ {
includePressure = includePressure_; this->includePressure = includePressure;
}
void GameModel::SetPerfectCircle(bool perfectCircle)
{
if (perfectCircle != this->perfectCircle)
{
this->perfectCircle = perfectCircle;
BuildBrushList();
}
} }

View File

@ -69,6 +69,7 @@ private:
unsigned int undoHistoryLimit; unsigned int undoHistoryLimit;
bool mouseClickRequired; bool mouseClickRequired;
bool includePressure; bool includePressure;
bool perfectCircle = true;
size_t activeColourPreset; size_t activeColourPreset;
std::vector<ui::Colour> colourPresets; std::vector<ui::Colour> colourPresets;
@ -133,6 +134,7 @@ public:
void BuildMenus(); void BuildMenus();
void BuildFavoritesMenu(); void BuildFavoritesMenu();
void BuildBrushList();
void BuildQuickOptionMenu(GameController * controller); void BuildQuickOptionMenu(GameController * controller);
std::deque<Snapshot*> GetHistory(); std::deque<Snapshot*> GetHistory();
@ -211,6 +213,7 @@ public:
void SetMouseClickRequired(bool mouseClickRequired); void SetMouseClickRequired(bool mouseClickRequired);
bool GetIncludePressure(); bool GetIncludePressure();
void SetIncludePressure(bool includePressure); void SetIncludePressure(bool includePressure);
void SetPerfectCircle(bool perfectCircle);
std::vector<Notification*> GetNotifications(); std::vector<Notification*> GetNotifications();
void AddNotification(Notification * notification); void AddNotification(Notification * notification);

View File

@ -107,6 +107,11 @@ void OptionsController::SetIncludePressure(bool includePressure)
model->SetIncludePressure(includePressure); model->SetIncludePressure(includePressure);
} }
void OptionsController::SetPerfectCircle(bool perfectCircle)
{
model->SetPerfectCircle(perfectCircle);
}
void OptionsController::Exit() void OptionsController::Exit()
{ {
view->CloseActiveWindow(); view->CloseActiveWindow();

View File

@ -32,6 +32,7 @@ public:
void SetShowAvatars(bool showAvatars); void SetShowAvatars(bool showAvatars);
void SetMouseClickrequired(bool mouseClickRequired); void SetMouseClickrequired(bool mouseClickRequired);
void SetIncludePressure(bool includePressure); void SetIncludePressure(bool includePressure);
void SetPerfectCircle(bool perfectCircle);
void Exit(); void Exit();
OptionsView * GetView(); OptionsView * GetView();

View File

@ -214,6 +214,18 @@ void OptionsModel::SetIncludePressure(bool includePressure)
notifySettingsChanged(); notifySettingsChanged();
} }
bool OptionsModel::GetPerfectCircle()
{
return Client::Ref().GetPrefBool("PerfectCircleBrush", true);
}
void OptionsModel::SetPerfectCircle(bool perfectCircle)
{
Client::Ref().SetPref("PerfectCircleBrush", perfectCircle);
gModel->SetPerfectCircle(perfectCircle);
notifySettingsChanged();
}
void OptionsModel::notifySettingsChanged() void OptionsModel::notifySettingsChanged()
{ {
for (size_t i = 0; i < observers.size(); i++) for (size_t i = 0; i < observers.size(); i++)

View File

@ -49,6 +49,8 @@ public:
void SetMouseClickRequired(bool mouseClickRequired); void SetMouseClickRequired(bool mouseClickRequired);
bool GetIncludePressure(); bool GetIncludePressure();
void SetIncludePressure(bool includePressure); void SetIncludePressure(bool includePressure);
bool GetPerfectCircle();
void SetPerfectCircle(bool perfectCircle);
virtual ~OptionsModel(); virtual ~OptionsModel();
}; };

View File

@ -260,6 +260,19 @@ OptionsView::OptionsView():
scrollPanel->AddChild(tempLabel); scrollPanel->AddChild(tempLabel);
scrollPanel->AddChild(includePressure); scrollPanel->AddChild(includePressure);
currentY+=20;
perfectCirclePressure = new ui::Checkbox(ui::Point(8, currentY), ui::Point(1, 16), "Perfect Circle", "");
autowidth(perfectCirclePressure);
perfectCirclePressure->SetActionCallback({ [this] { c->SetPerfectCircle(perfectCirclePressure->GetChecked()); } });
tempLabel = new ui::Label(ui::Point(perfectCirclePressure->Position.X+Graphics::textwidth(perfectCirclePressure->GetText())+20, currentY), ui::Point(1, 16), "\bg- Better circle brush, without incorrect points on edges");
autowidth(tempLabel);
tempLabel->Appearance.HorizontalAlign = ui::Appearance::AlignLeft;
tempLabel->Appearance.VerticalAlign = ui::Appearance::AlignMiddle;
scrollPanel->AddChild(tempLabel);
scrollPanel->AddChild(perfectCirclePressure);
//perfectCirclePressure
currentY+=20; currentY+=20;
decoSpace = new ui::DropDown(ui::Point(8, currentY), ui::Point(60, 16)); decoSpace = new ui::DropDown(ui::Point(8, currentY), ui::Point(60, 16));
decoSpace->SetActionCallback({ [this] { c->SetDecoSpace(decoSpace->GetOption().second); } }); decoSpace->SetActionCallback({ [this] { c->SetDecoSpace(decoSpace->GetOption().second); } });
@ -327,6 +340,7 @@ void OptionsView::NotifySettingsChanged(OptionsModel * sender)
showAvatars->SetChecked(sender->GetShowAvatars()); showAvatars->SetChecked(sender->GetShowAvatars());
mouseClickRequired->SetChecked(sender->GetMouseClickRequired()); mouseClickRequired->SetChecked(sender->GetMouseClickRequired());
includePressure->SetChecked(sender->GetIncludePressure()); includePressure->SetChecked(sender->GetIncludePressure());
perfectCirclePressure->SetChecked(sender->GetPerfectCircle());
} }
void OptionsView::AttachController(OptionsController * c_) void OptionsView::AttachController(OptionsController * c_)

View File

@ -33,6 +33,7 @@ class OptionsView: public ui::Window
ui::Checkbox * showAvatars; ui::Checkbox * showAvatars;
ui::Checkbox * mouseClickRequired; ui::Checkbox * mouseClickRequired;
ui::Checkbox * includePressure; ui::Checkbox * includePressure;
ui::Checkbox * perfectCirclePressure;
ui::ScrollPanel * scrollPanel; ui::ScrollPanel * scrollPanel;
public: public:
OptionsView(); OptionsView();