mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-21 01:05:59 +00:00
SHERLOCK: RT: Split tooltip text rendering into setText
This commit is contained in:
parent
77f256011a
commit
e92dca058e
@ -28,9 +28,95 @@ namespace Sherlock {
|
||||
|
||||
namespace Tattoo {
|
||||
|
||||
#define MAX_TOOLTIP_WIDTH 150
|
||||
|
||||
WidgetTooltip::WidgetTooltip(SherlockEngine *vm) : WidgetBase(vm) {
|
||||
}
|
||||
|
||||
void WidgetTooltip::setText(const Common::String &str) {
|
||||
Events &events = *_vm->_events;
|
||||
Common::Point mousePos = events.mousePos();
|
||||
bool reset = false;
|
||||
|
||||
// Make sure that the description is present
|
||||
if (!str.empty()) {
|
||||
int width = _surface.stringWidth(str) + 2;
|
||||
int height = _surface.stringHeight(str) + 2;
|
||||
Common::String line1 = str, line2 = "";
|
||||
|
||||
// See if we need to split it into two lines
|
||||
if (width > MAX_TOOLTIP_WIDTH) {
|
||||
// Go forward word by word to find out where to split the line
|
||||
const char *s = str.c_str();
|
||||
const char *space = nullptr;
|
||||
int dif = 10000;
|
||||
|
||||
for (;;) {
|
||||
// Find end of next word
|
||||
s = strchr(s + 1, ' ');
|
||||
|
||||
if (s == nullptr) {
|
||||
// Reached end of string
|
||||
if (space != nullptr) {
|
||||
line1 = Common::String(str.c_str(), space);
|
||||
line2 = Common::String(space + 1);
|
||||
height = _surface.stringHeight(line1) + _surface.stringHeight(line2) + 4;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Found space separating words, so see what width the string up to now is
|
||||
Common::String tempLine1 = Common::String(str.c_str(), s);
|
||||
Common::String tempLine2 = Common::String(s + 1);
|
||||
int width1 = _surface.stringWidth(tempLine1);
|
||||
int width2 = _surface.stringWidth(tempLine2);
|
||||
|
||||
// See if we've found a split point that results in a less overall width
|
||||
if (ABS(width1 - width2) < dif) {
|
||||
// Found a better split point
|
||||
dif = ABS(width1 - width2);
|
||||
space = s;
|
||||
line1 = tempLine1;
|
||||
line2 = tempLine2;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// No line split needed
|
||||
height = _surface.stringHeight(str) + 2;
|
||||
}
|
||||
|
||||
// Reallocate the text surface with the new size
|
||||
_surface.create(width, height);
|
||||
_surface.fill(TRANSPARENCY);
|
||||
|
||||
if (line2.empty()) {
|
||||
// Only a single line
|
||||
_surface.writeFancyString(str, Common::Point(0, 0), BLACK, INFO_TOP);
|
||||
} else {
|
||||
// Two lines to display
|
||||
int xp, yp;
|
||||
xp = (width - _surface.stringWidth(line1) - 2) / 2;
|
||||
_surface.writeFancyString(line1, Common::Point(xp, 0), BLACK, INFO_TOP);
|
||||
|
||||
xp = (width - _surface.stringWidth(line2) - 2) / 2;
|
||||
yp = _surface.stringHeight(line1) + 2;
|
||||
_surface.writeFancyString(line2, Common::Point(xp, yp), BLACK, INFO_TOP);
|
||||
}
|
||||
|
||||
// Set the initial display position for the tooltip text
|
||||
int tagX = CLIP(mousePos.x - width / 2, 0, SHERLOCK_SCREEN_WIDTH - width);
|
||||
int tagY = MAX(mousePos.y - height, 0);
|
||||
|
||||
_bounds = Common::Rect(tagX, tagY, tagX + width, tagY + height);
|
||||
} else {
|
||||
reset = true;
|
||||
}
|
||||
|
||||
if (reset && !_surface.empty()) {
|
||||
_surface.free();
|
||||
}
|
||||
}
|
||||
|
||||
void WidgetTooltip::execute() {
|
||||
Events &events = *_vm->_events;
|
||||
People &people = *_vm->_people;
|
||||
@ -38,7 +124,6 @@ void WidgetTooltip::execute() {
|
||||
Screen &screen = *_vm->_screen;
|
||||
TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
|
||||
Common::Point mousePos = events.mousePos();
|
||||
bool reset = false;
|
||||
|
||||
// See if thay are pointing at a different object and we need to regenerate the tooltip text
|
||||
if (ui._bgFound != ui._oldBgFound || (ui._bgFound != -1 && _surface.empty()) ||
|
||||
@ -63,85 +148,9 @@ void WidgetTooltip::execute() {
|
||||
str = scene._exits[ui._arrowZone]._dest;
|
||||
}
|
||||
|
||||
// Make sure that the description is present
|
||||
if (!str.empty() && !str.hasPrefix(" ")) {
|
||||
int width = screen.stringWidth(str) + 2;
|
||||
int height = screen.stringHeight(str) + 2;
|
||||
Common::String line1 = str, line2 = "";
|
||||
|
||||
// See if we need to split it into two lines
|
||||
if (width > 150) {
|
||||
// Go forward word by word to find out where to split the line
|
||||
const char *s = str.c_str();
|
||||
const char *space = nullptr;
|
||||
int dif = 10000;
|
||||
|
||||
for (;;) {
|
||||
// Find end of next word
|
||||
s = strchr(s + 1, ' ');
|
||||
|
||||
if (s == nullptr) {
|
||||
// Reached end of string
|
||||
if (space != nullptr) {
|
||||
line1 = Common::String(str.c_str(), space);
|
||||
line2 = Common::String(space + 1);
|
||||
height = screen.stringHeight(line1) + screen.stringHeight(line2) + 4;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Found space separating words, so see what width the string up to now is
|
||||
Common::String tempLine1 = Common::String(str.c_str(), s);
|
||||
Common::String tempLine2 = Common::String(s + 1);
|
||||
int width1 = screen.stringWidth(tempLine1);
|
||||
int width2 = screen.stringWidth(tempLine2);
|
||||
|
||||
// See if we've found a split point that results in a less overall width
|
||||
if (ABS(width1 - width2) < dif) {
|
||||
// Found a better split point
|
||||
dif = ABS(width1 - width2);
|
||||
space = s;
|
||||
line1 = tempLine1;
|
||||
line2 = tempLine2;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// No line split needed
|
||||
height = screen.stringHeight(str) + 2;
|
||||
}
|
||||
|
||||
// Reallocate the text surface with the new size
|
||||
_surface.create(width, height);
|
||||
_surface.fill(TRANSPARENCY);
|
||||
|
||||
if (line2.empty()) {
|
||||
// Only a single line
|
||||
_surface.writeFancyString(str, Common::Point(0, 0), BLACK, INFO_TOP);
|
||||
} else {
|
||||
// Two lines to display
|
||||
int xp, yp;
|
||||
xp = (width - screen.stringWidth(line1) - 2) / 2;
|
||||
_surface.writeFancyString(line1, Common::Point(xp, 0), BLACK, INFO_TOP);
|
||||
|
||||
xp = (width - screen.stringWidth(line2) - 2) / 2;
|
||||
yp = screen.stringHeight(line1) + 2;
|
||||
_surface.writeFancyString(line2, Common::Point(xp, yp), BLACK, INFO_TOP);
|
||||
}
|
||||
|
||||
// Set the initial display position for the tooltip text
|
||||
int tagX = CLIP(mousePos.x - width / 2, 0, SHERLOCK_SCREEN_WIDTH - width);
|
||||
int tagY = MAX(mousePos.y - height, 0);
|
||||
|
||||
_bounds = Common::Rect(tagX, tagY, tagX + width, tagY + height);
|
||||
} else {
|
||||
reset = true;
|
||||
}
|
||||
setText(str.hasPrefix(" ") ? Common::String() : str);
|
||||
} else if ((ui._bgFound == -1 && ui._oldBgFound != -1) || (ui._arrowZone == -1 && ui._oldArrowZone != -1)) {
|
||||
reset = true;
|
||||
}
|
||||
|
||||
if (reset && !_surface.empty()) {
|
||||
_surface.free();
|
||||
setText("");
|
||||
}
|
||||
|
||||
ui._oldBgFound = ui._bgFound;
|
||||
|
@ -38,6 +38,11 @@ public:
|
||||
WidgetTooltip(SherlockEngine *vm);
|
||||
virtual ~WidgetTooltip() {}
|
||||
|
||||
/**
|
||||
* Set the text for the tooltip
|
||||
*/
|
||||
void setText(const Common::String &str);
|
||||
|
||||
/**
|
||||
* Handle updating the tooltip state
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user