Clean up sign-related code a bit

Also draw search signs with purple text and thread signs with red.
This commit is contained in:
Tamás Bálint Misius 2019-04-12 17:09:34 +02:00
parent 59afaec70f
commit 9d92b77163
No known key found for this signature in database
GPG Key ID: 5B472A12F6ECA9F2
9 changed files with 235 additions and 244 deletions

View File

@ -58,34 +58,14 @@ int PIXELMETHODS_CLASS::drawtext(int x, int y, String str, int r, int g, int b,
if(!s[1]) break;
switch (s[1])
{
case 'w':
r = g = b = 255;
break;
case 'g':
r = g = b = 192;
break;
case 'o':
r = 255;
g = 216;
b = 32;
break;
case 'r':
r = 255;
g = b = 0;
break;
case 'l':
r = 255;
g = b = 75;
break;
case 'b':
r = g = 0;
b = 255;
break;
case 't':
b = 255;
g = 170;
r = 32;
break;
case 'w': r = 255; g = 255; b = 255; break;
case 'g': r = 192; g = 192; b = 192; break;
case 'o': r = 255; g = 216; b = 32; break;
case 'r': r = 255; g = 0; b = 0; break;
case 'l': r = 255; g = 75; b = 75; break;
case 'b': r = 0; g = 0; b = 255; break;
case 't': b = 255; g = 170; r = 32; break;
case 'u': r = 147; g = 83; b = 211; break;
}
if(invert)
{

View File

@ -981,28 +981,21 @@ void Renderer::DrawSigns()
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, partsFbo);
glTranslated(0, MENUSIZE, 0);
#endif
for (size_t i = 0; i < signs.size(); i++)
if (signs[i].text.length())
for (auto &currentSign : signs)
{
String::value_type type = 0;
String text = signs[i].getText(sim);
sign::splitsign(signs[i].text, &type);
signs[i].pos(text, x, y, w, h);
if (currentSign.text.length())
{
String text = currentSign.getDisplayText(sim, x, y, w, h);
clearrect(x, y, w+1, h);
drawrect(x, y, w+1, h, 192, 192, 192, 255);
if (!type)
drawtext(x+3, y+3, text, 255, 255, 255, 255);
else if(type == 'b')
drawtext(x+3, y+3, text, 211, 211, 40, 255);
else
drawtext(x+3, y+3, text, 0, 191, 255, 255);
if (signs[i].ju != sign::None)
if (currentSign.ju != sign::None)
{
int x = signs[i].x;
int y = signs[i].y;
int dx = 1 - signs[i].ju;
int dy = (signs[i].y > 18) ? -1 : 1;
int x = currentSign.x;
int y = currentSign.y;
int dx = 1 - currentSign.ju;
int dy = (currentSign.y > 18) ? -1 : 1;
#ifdef OGLR
glBegin(GL_LINES);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
@ -1019,6 +1012,7 @@ void Renderer::DrawSigns()
#endif
}
}
}
#ifdef OGLR
glTranslated(0, -MENUSIZE, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, prevFbo);

View File

@ -311,7 +311,7 @@ int GameController::GetSignAt(int x, int y)
for (int i = sim->signs.size()-1; i >= 0; i--)
{
int signx, signy, signw, signh;
sim->signs[i].pos(sim->signs[i].getText(sim), signx, signy, signw, signh);
sim->signs[i].getDisplayText(sim, signx, signy, signw, signh);
if (x>=signx && x<=signx+signw && y>=signy && y<=signy+signh)
return i;
}
@ -324,6 +324,11 @@ String GameController::GetSignText(int signID)
return gameModel->GetSimulation()->signs[signID].text;
}
std::pair<int, sign::Type> GameController::GetSignSplit(int signID)
{
return gameModel->GetSimulation()->signs[signID].split();
}
void GameController::PlaceSave(ui::Point position, bool includePressure)
{
bool incPressure = Client::Ref().GetPrefBool("Simulation.LoadPressure", true);
@ -640,12 +645,13 @@ bool GameController::MouseDown(int x, int y, unsigned button)
foundSignID = GetSignAt(x, y);
if (foundSignID != -1)
{
sign foundSign = gameModel->GetSimulation()->signs[foundSignID];
if (sign::splitsign(foundSign.text))
if (gameModel->GetSimulation()->signs[foundSignID].split().first)
{
return false;
}
}
}
}
return ret;
}
@ -665,40 +671,31 @@ bool GameController::MouseUp(int x, int y, unsigned button, char type)
int foundSignID = GetSignAt(x, y);
if (foundSignID != -1)
{
sign foundSign = gameModel->GetSimulation()->signs[foundSignID];
sign &foundSign = gameModel->GetSimulation()->signs[foundSignID];
String str = foundSign.text;
String::value_type type;
int pos = sign::splitsign(str, &type);
if (pos)
auto si = gameModel->GetSimulation()->signs[foundSignID].split();
if (si.first)
{
ret = false;
if (type == 'c' || type == 't' || type == 's')
switch (si.second)
{
String link = str.Substr(3, pos-3);
switch (type)
case sign::Type::Save:
{
case 'c':
{
int saveID = link.ToNumber<int>(true);
int saveID = str.Substr(3, si.first - 3).ToNumber<int>(true);
if (saveID)
OpenSavePreview(saveID, 0, false);
}
break;
}
case 't':
{
// buff is already confirmed to be a number by sign::splitsign
Platform::OpenURI(ByteString::Build(SCHEME "powdertoy.co.uk/Discussions/Thread/View.html?Thread=", link.ToUtf8()));
case sign::Type::Thread:
Platform::OpenURI(ByteString::Build(SCHEME "powdertoy.co.uk/Discussions/Thread/View.html?Thread=", str.Substr(3, si.first - 3).ToUtf8()));
break;
}
case 's':
OpenSearch(link);
case sign::Type::Search:
OpenSearch(str.Substr(3, si.first - 3));
break;
}
}
else if (type == 'b')
{
Simulation * sim = gameModel->GetSimulation();
sim->create_part(-1, foundSign.x, foundSign.y, PT_SPRK);
case sign::Type::Button:
gameModel->GetSimulation()->create_part(-1, foundSign.x, foundSign.y, PT_SPRK);
break;
default: break;
}
}
}

View File

@ -59,6 +59,7 @@ public:
GameView * GetView();
int GetSignAt(int x, int y);
String GetSignText(int signID);
std::pair<int, sign::Type> GetSignSplit(int signID);
bool MouseMove(int x, int y, int dx, int dy);
bool MouseDown(int x, int y, unsigned button);

View File

@ -1726,24 +1726,25 @@ void GameView::OnTick(float dt)
if (foundSignID != -1)
{
String str = c->GetSignText(foundSignID);
String::value_type type = '\0';
int pos = sign::splitsign(str, &type);
if (type == 'c' || type == 't' || type == 's')
{
String linkSign = str.Substr(3, pos-3);
auto si = c->GetSignSplit(foundSignID);
StringBuilder tooltip;
switch (type)
switch (si.second)
{
case 'c':
tooltip << "Go to save ID:" << linkSign;
case sign::Type::Save:
tooltip << "Go to save ID:" << str.Substr(3, si.first - 3);
break;
case 't':
tooltip << "Open forum thread " << linkSign << " in browser";
case sign::Type::Thread:
tooltip << "Open forum thread " << str.Substr(3, si.first - 3) << " in browser";
break;
case 's':
tooltip << "Search for " << linkSign;
case sign::Type::Search:
tooltip << "Search for " << str.Substr(3, si.first - 3);
break;
default: break;
}
if (tooltip.Size())
{
ToolTip(ui::Point(0, Size.Y), tooltip.Build());
}
}

View File

@ -193,23 +193,15 @@ void SignWindow::OnTryExit(ui::Window::ExitMethod method)
void SignWindow::DoDraw()
{
for(std::vector<sign>::iterator iter = sim->signs.begin(), end = sim->signs.end(); iter != end; ++iter)
for (auto &currentSign : sim->signs)
{
sign & currentSign = *iter;
int x, y, w, h, dx, dy;
String::value_type type = 0;
Graphics * g = GetGraphics();
String text = currentSign.getText(sim);
sign::splitsign(currentSign.text, &type);
currentSign.pos(text, x, y, w, h);
String text = currentSign.getDisplayText(sim, x, y, w, h);
g->clearrect(x, y, w+1, h);
g->drawrect(x, y, w+1, h, 192, 192, 192, 255);
if (!type)
g->drawtext(x+3, y+3, text, 255, 255, 255, 255);
else if(type == 'b')
g->drawtext(x+3, y+3, text, 211, 211, 40, 255);
else
g->drawtext(x+3, y+3, text, 0, 191, 255, 255);
if (currentSign.ju != sign::None)
{
@ -294,7 +286,7 @@ void SignTool::Click(Simulation * sim, Brush * brush, ui::Point position)
int signX, signY, signW, signH, signIndex = -1;
for (size_t i = 0; i < sim->signs.size(); i++)
{
sim->signs[i].pos(sim->signs[i].getText(sim), signX, signY, signW, signH);
sim->signs[i].getDisplayText(sim, signX, signY, signW, signH);
if (position.X > signX && position.X < signX+signW && position.Y > signY && position.Y < signY+signH)
{
signIndex = i;

View File

@ -564,10 +564,11 @@ int LuaScriptInterface::simulation_signIndex(lua_State *l)
return lua_pushnil(l), 1;
}
int x, y, w, h;
if (!key.compare("text"))
return lua_pushstring(l, luacon_sim->signs[id].text.ToUtf8().c_str()), 1;
else if (!key.compare("displayText"))
return lua_pushstring(l, luacon_sim->signs[id].getText(luacon_sim).ToUtf8().c_str()), 1;
return lua_pushstring(l, luacon_sim->signs[id].getDisplayText(luacon_sim, x, y, w, h, false).ToUtf8().c_str()), 1;
else if (!key.compare("justification"))
return lua_pushnumber(l, (int)luacon_sim->signs[id].ju), 1;
else if (!key.compare("x"))
@ -576,29 +577,25 @@ int LuaScriptInterface::simulation_signIndex(lua_State *l)
return lua_pushnumber(l, luacon_sim->signs[id].y), 1;
else if (!key.compare("screenX"))
{
int x, y, w, h;
luacon_sim->signs[id].pos(luacon_sim->signs[id].getText(luacon_sim), x, y, w, h);
luacon_sim->signs[id].getDisplayText(luacon_sim, x, y, w, h);
lua_pushnumber(l, x);
return 1;
}
else if (!key.compare("screenY"))
{
int x, y, w, h;
luacon_sim->signs[id].pos(luacon_sim->signs[id].getText(luacon_sim), x, y, w, h);
luacon_sim->signs[id].getDisplayText(luacon_sim, x, y, w, h);
lua_pushnumber(l, y);
return 1;
}
else if (!key.compare("width"))
{
int x, y, w, h;
luacon_sim->signs[id].pos(luacon_sim->signs[id].getText(luacon_sim), x, y, w, h);
luacon_sim->signs[id].getDisplayText(luacon_sim, x, y, w, h);
lua_pushnumber(l, w);
return 1;
}
else if (!key.compare("height"))
{
int x, y, w, h;
luacon_sim->signs[id].pos(luacon_sim->signs[id].getText(luacon_sim), x, y, w, h);
luacon_sim->signs[id].getDisplayText(luacon_sim, x, y, w, h);
lua_pushnumber(l, h);
return 1;
}

View File

@ -11,70 +11,23 @@ sign::sign(String text_, int x_, int y_, Justification justification_):
{
}
void sign::pos(String signText, int & x0, int & y0, int & w, int & h)
{
w = Graphics::textwidth(signText.c_str()) + 5;
h = 15;
x0 = (ju == Right) ? x - w :
(ju == Left) ? x : x - w/2;
y0 = (y > 18) ? y - 18 : y + 4;
}
int sign::splitsign(String str, String::value_type *type)
{
if (str[0] == '{' && (str[1] == 'c' || str[1] == 't' || str[1] == 'b' || str[1] == 's'))
{
size_t strIndex = 2;
// Signs with text arguments
if (str[1] == 's')
{
if (str[2] == ':')
{
strIndex = 3;
while (strIndex < str.length() && str[strIndex] != '|')
strIndex++;
}
else
return 0;
}
// Signs with number arguments
if (str[1] == 'c' || str[1] == 't')
{
if (str[2] == ':' && str[3] >= '0' && str[3] <= '9')
{
strIndex = 4;
while (str[strIndex] >= '0' && str[strIndex] <= '9')
strIndex++;
}
else
return 0;
}
if (str[strIndex] == '|')
{
if (str[str.length() - 1] == '}')
{
if (type)
*type = str[1];
return strIndex;
}
}
}
return 0;
}
String sign::getText(Simulation *sim)
String sign::getDisplayText(Simulation *sim, int &x0, int &y0, int &w, int &h, bool colorize)
{
String drawable_text;
auto si = std::make_pair(0, Type::Normal);
if (text.find('{') == text.npos)
{
return text;
drawable_text = text;
}
if (int pos = splitsign(text))
else
{
return text.Between(pos + 1, text.size() - 1);
si = split();
if (si.first)
{
drawable_text = text.Between(si.first + 1, text.size() - 1);
}
else
{
Particle const *part = nullptr;
float pressure = 0.0f;
float aheat = 0.0f;
@ -145,5 +98,66 @@ String sign::getText(Simulation *sim)
}
}
formatted_text << remaining_text;
return formatted_text.Build();
drawable_text = formatted_text.Build();
}
}
if (colorize)
{
switch (si.second)
{
case Normal: break;
case Save: drawable_text = "\bt" + drawable_text; break;
case Thread: drawable_text = "\bl" + drawable_text; break;
case Button: drawable_text = "\bo" + drawable_text; break;
case Search: drawable_text = "\bu" + drawable_text; break;
}
}
w = Graphics::textwidth(drawable_text.c_str()) + 5;
h = 15;
x0 = (ju == Right) ? x - w : (ju == Left) ? x : x - w/2;
y0 = (y > 18) ? y - 18 : y + 4;
return drawable_text;
}
std::pair<int, sign::Type> sign::split()
{
String::size_type pipe = 0;
if (text.size() >= 4 && text.front() == '{' && text.back() == '}')
{
switch (text[1])
{
case 'c':
case 't':
if (text[2] == ':' && (pipe = text.find('|', 4)) != text.npos)
{
for (String::size_type i = 3; i < pipe; ++i)
{
if (text[i] < '0' || text[i] > '9')
{
return std::make_pair(0, Type::Normal);
}
}
return std::make_pair(pipe, text[1] == 'c' ? Type::Save : Type::Thread);
}
break;
case 'b':
if (text[2] == '|')
{
return std::make_pair(2, Type::Button);
}
break;
case 's':
if (text[2] == ':' && (pipe = text.find('|', 3)) != text.npos)
{
return std::make_pair(pipe, Type::Search);
}
break;
}
}
return std::make_pair(0, Type::Normal);
}

View File

@ -3,21 +3,36 @@
#include "common/String.h"
#include <utility>
class Simulation;
class sign
struct sign
{
public:
enum Justification { Left = 0, Middle = 1, Right = 2, None = 3 };
sign(String text_, int x_, int y_, Justification justification_);
enum Justification
{
Left = 0,
Middle = 1,
Right = 2,
None = 3
};
enum Type
{
Normal,
Save,
Thread,
Button,
Search
};
int x, y;
Justification ju;
String text;
String getText(Simulation *sim);
void pos(String signText, int & x0, int & y0, int & w, int & h);
static int splitsign(String str, String::value_type *type = NULL);
sign(String text_, int x_, int y_, Justification justification_);
String getDisplayText(Simulation *sim, int &x, int &y, int &w, int &h, bool colorize = true);
std::pair<int, Type> split();
};
#endif