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
*.config
*.creator*
*.cflags
*.cxxflags
*.files
*.includes
config.log

View File

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

View File

@ -111,29 +111,8 @@ GameModel::GameModel():
BuildMenus();
//Set default brush palette
brushList.push_back(new EllipseBrush(ui::Point(4, 4)));
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)));
}
perfectCircle = Client::Ref().GetPrefBool("PerfectCircleBrush", true);
BuildBrushList();
//Set default decoration colour
unsigned char colourR = std::min(Client::Ref().GetPrefInteger("Decoration.Red", 200), 255);
@ -428,6 +407,45 @@ void GameModel::BuildFavoritesMenu()
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)
{
for (auto *menu : menuList)
@ -1328,9 +1346,9 @@ bool GameModel::GetMouseClickRequired()
return mouseClickRequired;
}
void GameModel::SetMouseClickRequired(bool mouseClickRequired_)
void GameModel::SetMouseClickRequired(bool mouseClickRequired)
{
mouseClickRequired = mouseClickRequired_;
this->mouseClickRequired = mouseClickRequired;
}
bool GameModel::GetIncludePressure()
@ -1338,7 +1356,16 @@ bool GameModel::GetIncludePressure()
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;
bool mouseClickRequired;
bool includePressure;
bool perfectCircle = true;
size_t activeColourPreset;
std::vector<ui::Colour> colourPresets;
@ -133,6 +134,7 @@ public:
void BuildMenus();
void BuildFavoritesMenu();
void BuildBrushList();
void BuildQuickOptionMenu(GameController * controller);
std::deque<Snapshot*> GetHistory();
@ -211,6 +213,7 @@ public:
void SetMouseClickRequired(bool mouseClickRequired);
bool GetIncludePressure();
void SetIncludePressure(bool includePressure);
void SetPerfectCircle(bool perfectCircle);
std::vector<Notification*> GetNotifications();
void AddNotification(Notification * notification);

View File

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

View File

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

View File

@ -214,6 +214,18 @@ void OptionsModel::SetIncludePressure(bool includePressure)
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()
{
for (size_t i = 0; i < observers.size(); i++)

View File

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

View File

@ -260,6 +260,19 @@ OptionsView::OptionsView():
scrollPanel->AddChild(tempLabel);
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;
decoSpace = new ui::DropDown(ui::Point(8, currentY), ui::Point(60, 16));
decoSpace->SetActionCallback({ [this] { c->SetDecoSpace(decoSpace->GetOption().second); } });
@ -327,6 +340,7 @@ void OptionsView::NotifySettingsChanged(OptionsModel * sender)
showAvatars->SetChecked(sender->GetShowAvatars());
mouseClickRequired->SetChecked(sender->GetMouseClickRequired());
includePressure->SetChecked(sender->GetIncludePressure());
perfectCirclePressure->SetChecked(sender->GetPerfectCircle());
}
void OptionsView::AttachController(OptionsController * c_)

View File

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