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;
|
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
|
* 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.
|
* 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;
|
void Save(IniFile &ini) const;
|
||||||
|
|
||||||
int CheckMatch(uint16_t keycode, bool global_only = false) const;
|
int CheckMatch(uint16_t keycode, bool global_only = false) const;
|
||||||
|
const Hotkey* GetHotkeyByNum(int num) const;
|
||||||
|
|
||||||
GlobalHotkeyHandlerFunc global_hotkey_handler;
|
GlobalHotkeyHandlerFunc global_hotkey_handler;
|
||||||
private:
|
private:
|
||||||
|
@ -64,5 +65,6 @@ void SaveHotkeysToConfig();
|
||||||
|
|
||||||
|
|
||||||
void HandleGlobalHotkeys(char32_t key, uint16_t keycode);
|
void HandleGlobalHotkeys(char32_t key, uint16_t keycode);
|
||||||
|
std::string KeycodeToShortString(uint16_t keycode);
|
||||||
|
|
||||||
#endif /* HOTKEYS_H */
|
#endif /* HOTKEYS_H */
|
||||||
|
|
|
@ -27,6 +27,9 @@
|
||||||
|
|
||||||
#include "safeguards.h"
|
#include "safeguards.h"
|
||||||
|
|
||||||
|
#include "widgets/toolbar_widget.h"
|
||||||
|
#include "hotkeys.h"
|
||||||
|
|
||||||
WidgetDimensions WidgetDimensions::scaled = {};
|
WidgetDimensions WidgetDimensions::scaled = {};
|
||||||
|
|
||||||
static std::string GetStringForWidget(const Window *w, const NWidgetCore *nwid, bool secondary = false)
|
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);
|
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 SetupSmallestSize(Window *w) override;
|
||||||
void Draw(const Window *w) override;
|
void Draw(const Window *w) override;
|
||||||
|
void DrawHotkeyHint(const Window* window);
|
||||||
|
|
||||||
bool ButtonHit(const Point &pt);
|
bool ButtonHit(const Point &pt);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue