mirror of https://github.com/OpenTTD/OpenTTD
Feature: WIP: Draw hotkey hints over some widgets
parent
679f95d1de
commit
a92619be89
|
@ -196,6 +196,40 @@ static std::string KeycodeToString(uint16_t keycode)
|
|||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* A short representation of the keycode, for printing as a hotkey hint.
|
||||
* @param keycode The keycode to convert to a string.
|
||||
* @return A string representation of this keycode.
|
||||
*/
|
||||
std::string KeycodeToShortString(uint16_t keycode)
|
||||
{
|
||||
std::string str;
|
||||
if (keycode & WKC_SHIFT) {
|
||||
// TODO
|
||||
str += "»";
|
||||
}
|
||||
if (keycode & WKC_CTRL) {
|
||||
str += "^";
|
||||
}
|
||||
if (keycode & WKC_ALT) {
|
||||
str += "A+";
|
||||
}
|
||||
if (keycode & WKC_META) {
|
||||
str += "M+";
|
||||
}
|
||||
keycode = keycode & ~WKC_SPECIAL_KEYS;
|
||||
|
||||
for (const auto &kn : _keycode_to_name) {
|
||||
if (kn.keycode == keycode) {
|
||||
str += kn.name;
|
||||
return str;
|
||||
}
|
||||
}
|
||||
assert(keycode < 128);
|
||||
str.push_back(keycode);
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert all keycodes attached to a hotkey to a single string. If multiple
|
||||
* keycodes are attached to the hotkey they are split by a comma.
|
||||
|
@ -350,3 +384,12 @@ void HandleGlobalHotkeys([[maybe_unused]] char32_t key, uint16_t keycode)
|
|||
}
|
||||
}
|
||||
|
||||
const Hotkey* HotkeyList::GetHotkeyByNum(int num) const
|
||||
{
|
||||
for (const Hotkey &hotkey : this->items) {
|
||||
if (hotkey.num == num) {
|
||||
return &hotkey;
|
||||
}
|
||||
}
|
||||
return (const Hotkey*) nullptr;
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ struct HotkeyList {
|
|||
void Save(IniFile &ini) const;
|
||||
|
||||
int CheckMatch(uint16_t keycode, bool global_only = false) const;
|
||||
const Hotkey* GetHotkeyByNum(int num) const;
|
||||
|
||||
GlobalHotkeyHandlerFunc global_hotkey_handler;
|
||||
private:
|
||||
|
@ -64,5 +65,6 @@ void SaveHotkeysToConfig();
|
|||
|
||||
|
||||
void HandleGlobalHotkeys(char32_t key, uint16_t keycode);
|
||||
std::string KeycodeToShortString(uint16_t keycode);
|
||||
|
||||
#endif /* HOTKEYS_H */
|
||||
|
|
|
@ -27,6 +27,9 @@
|
|||
|
||||
#include "safeguards.h"
|
||||
|
||||
#include "widgets/toolbar_widget.h"
|
||||
#include "hotkeys.h"
|
||||
|
||||
WidgetDimensions WidgetDimensions::scaled = {};
|
||||
|
||||
static std::string GetStringForWidget(const Window *w, const NWidgetCore *nwid, bool secondary = false)
|
||||
|
@ -3108,6 +3111,63 @@ void NWidgetLeaf::Draw(const Window *w)
|
|||
}
|
||||
|
||||
DrawOutline(w, this);
|
||||
|
||||
// TODO: Draw hints only if Alt is being held.
|
||||
if (!this->IsDisabled()) {
|
||||
this->DrawHotkeyHint(w);
|
||||
}
|
||||
}
|
||||
|
||||
void NWidgetLeaf::DrawHotkeyHint(const Window* w) {
|
||||
// TODO: Use global hotkey for autoroads for rail, road, tram, etc. if
|
||||
// they have been set.
|
||||
|
||||
// TODO: Rect is wrong for edit boxes, and the kind of hint we're showing
|
||||
// will look bad anyway.
|
||||
Rect r = this->GetCurrentRect().Shrink(1);
|
||||
if (w->window_desc.cls == WC_MAIN_TOOLBAR && this->index == WID_TN_FAST_FORWARD) {
|
||||
// Special-case hint text for Fast-forwards because it's not really a hotkey
|
||||
DrawStringMultiLine(r, "Tab", TC_WHITE, SA_LEFT | SA_BOTTOM, false, FS_NORMAL);
|
||||
} else if (w->window_desc.hotkeys != nullptr) {
|
||||
// Widget IDs can coincidentally overlap with hotkey IDs if
|
||||
// they aren't assigned properly. Avoid this.
|
||||
auto hk = w->window_desc.hotkeys->GetHotkeyByNum(this->index);
|
||||
if (hk != nullptr) {
|
||||
if (hk->keycodes.size()) {
|
||||
// Find the "best" of the available keycodes
|
||||
auto keycode = *(hk->keycodes.begin());
|
||||
for (auto k : hk->keycodes) {
|
||||
if (!(keycode & WKC_GLOBAL_HOTKEY) && (k & WKC_GLOBAL_HOTKEY)) {
|
||||
keycode = k;
|
||||
} else if ('A' <= (k & ~WKC_SPECIAL_KEYS) && (k & ~WKC_SPECIAL_KEYS) <= 'Z') {
|
||||
keycode = k;
|
||||
}
|
||||
}
|
||||
|
||||
// Convert to a string
|
||||
// TODO: Glyphs for Shift, Alt, etc. Colour for global.
|
||||
// - On screen keyboard has a sprite for shift.
|
||||
auto s = KeycodeToShortString(keycode);
|
||||
|
||||
// Choose the font-size
|
||||
auto availableSize = Dimension(r.right - r.left, r.bottom - r.top);
|
||||
auto desiredSize = GetStringBoundingBox(s, FS_NORMAL);
|
||||
auto fontsize = FS_NORMAL;
|
||||
if (availableSize < desiredSize) {
|
||||
fontsize = FS_SMALL;
|
||||
}
|
||||
|
||||
// Display the hints!
|
||||
// TODO: not as readable as my mockup :(
|
||||
// - Outline or a bolder font could help.
|
||||
auto colour = TC_WHITE;
|
||||
if (keycode & WKC_GLOBAL_HOTKEY) {
|
||||
colour = TC_YELLOW;
|
||||
}
|
||||
DrawStringMultiLine(r, s, colour, SA_LEFT | SA_BOTTOM, false, fontsize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -922,6 +922,7 @@ public:
|
|||
|
||||
void SetupSmallestSize(Window *w) override;
|
||||
void Draw(const Window *w) override;
|
||||
void DrawHotkeyHint(const Window* window);
|
||||
|
||||
bool ButtonHit(const Point &pt);
|
||||
|
||||
|
|
Loading…
Reference in New Issue