Add "perfect circle brush" option (on by default), to allow using old circle brush
This commit is contained in:
parent
cb419cd85c
commit
1e23269dd4
2
.gitignore
vendored
2
.gitignore
vendored
@ -56,6 +56,8 @@ Makefile.me
|
||||
*.layout
|
||||
*.config
|
||||
*.creator*
|
||||
*.cflags
|
||||
*.cxxflags
|
||||
*.files
|
||||
*.includes
|
||||
config.log
|
||||
|
@ -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++)
|
||||
{
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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++)
|
||||
|
@ -49,6 +49,8 @@ public:
|
||||
void SetMouseClickRequired(bool mouseClickRequired);
|
||||
bool GetIncludePressure();
|
||||
void SetIncludePressure(bool includePressure);
|
||||
bool GetPerfectCircle();
|
||||
void SetPerfectCircle(bool perfectCircle);
|
||||
virtual ~OptionsModel();
|
||||
};
|
||||
|
||||
|
@ -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_)
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user