Changeset View
Standalone View
source/gui/CGUI.cpp
Show First 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | |||||
extern int g_yres; | extern int g_yres; | ||||
const double SELECT_DBLCLICK_RATE = 0.5; | const double SELECT_DBLCLICK_RATE = 0.5; | ||||
const u32 MAX_OBJECT_DEPTH = 100; // Max number of nesting for GUI includes. Used to detect recursive inclusion | const u32 MAX_OBJECT_DEPTH = 100; // Max number of nesting for GUI includes. Used to detect recursive inclusion | ||||
const CStr CGUI::EventNameLoad = "Load"; | const CStr CGUI::EventNameLoad = "Load"; | ||||
const CStr CGUI::EventNameTick = "Tick"; | const CStr CGUI::EventNameTick = "Tick"; | ||||
const CStr CGUI::EventNamePress = "Press"; | const CStr CGUI::EventNamePress = "Press"; | ||||
const CStr CGUI::EventNameKeyDown = "KeyDown"; | |||||
const CStr CGUI::EventNameRelease = "Release"; | const CStr CGUI::EventNameRelease = "Release"; | ||||
const CStr CGUI::EventNameMouseRightPress = "MouseRightPress"; | const CStr CGUI::EventNameMouseRightPress = "MouseRightPress"; | ||||
const CStr CGUI::EventNameMouseLeftPress = "MouseLeftPress"; | const CStr CGUI::EventNameMouseLeftPress = "MouseLeftPress"; | ||||
const CStr CGUI::EventNameMouseWheelDown = "MouseWheelDown"; | const CStr CGUI::EventNameMouseWheelDown = "MouseWheelDown"; | ||||
const CStr CGUI::EventNameMouseWheelUp = "MouseWheelUp"; | const CStr CGUI::EventNameMouseWheelUp = "MouseWheelUp"; | ||||
const CStr CGUI::EventNameMouseLeftDoubleClick = "MouseLeftDoubleClick"; | const CStr CGUI::EventNameMouseLeftDoubleClick = "MouseLeftDoubleClick"; | ||||
const CStr CGUI::EventNameMouseLeftRelease = "MouseLeftRelease"; | const CStr CGUI::EventNameMouseLeftRelease = "MouseLeftRelease"; | ||||
const CStr CGUI::EventNameMouseRightDoubleClick = "MouseRightDoubleClick"; | const CStr CGUI::EventNameMouseRightDoubleClick = "MouseRightDoubleClick"; | ||||
Show All 20 Lines | CGUI::~CGUI() | ||||
for (const std::pair<CStr, const CGUISprite*>& p : m_Sprites) | for (const std::pair<CStr, const CGUISprite*>& p : m_Sprites) | ||||
delete p.second; | delete p.second; | ||||
} | } | ||||
InReaction CGUI::HandleEvent(const SDL_Event_* ev) | InReaction CGUI::HandleEvent(const SDL_Event_* ev) | ||||
{ | { | ||||
InReaction ret = IN_PASS; | InReaction ret = IN_PASS; | ||||
if (ev->ev.type == SDL_HOTKEYDOWN || ev->ev.type == SDL_HOTKEYUP) | if (ev->ev.type == SDL_HOTKEYDOWN || ev->ev.type == SDL_HOTKEYPRESS || ev->ev.type == SDL_HOTKEYUP) | ||||
{ | { | ||||
const char* hotkey = static_cast<const char*>(ev->ev.user.data1); | const char* hotkey = static_cast<const char*>(ev->ev.user.data1); | ||||
if (m_GlobalHotkeys.find(hotkey) != m_GlobalHotkeys.end() && ev->ev.type == SDL_HOTKEYDOWN) | const CStr& eventName = ev->ev.type == SDL_HOTKEYPRESS ? EventNamePress : ev->ev.type == SDL_HOTKEYDOWN ? EventNameKeyDown : EventNameRelease; | ||||
if (m_GlobalHotkeys.find(hotkey) != m_GlobalHotkeys.end() && m_GlobalHotkeys[hotkey].find(eventName) != m_GlobalHotkeys[hotkey].end()) | |||||
{ | { | ||||
ret = IN_HANDLED; | ret = IN_HANDLED; | ||||
JSContext* cx = m_ScriptInterface->GetContext(); | JSContext* cx = m_ScriptInterface->GetContext(); | ||||
wraitii: This copies the string every time, which is rather unlucky for performance.
You can either go… | |||||
JSAutoRequest rq(cx); | JSAutoRequest rq(cx); | ||||
JS::RootedObject globalObj(cx, &GetGlobalObject().toObject()); | JS::RootedObject globalObj(cx, &GetGlobalObject().toObject()); | ||||
JS::RootedValue result(cx); | JS::RootedValue result(cx); | ||||
JS_CallFunctionValue(cx, globalObj, m_GlobalHotkeys[hotkey], JS::HandleValueArray::empty(), &result); | JS_CallFunctionValue(cx, globalObj, m_GlobalHotkeys[hotkey][eventName], JS::HandleValueArray::empty(), &result); | ||||
} | } | ||||
std::map<CStr, std::vector<IGUIObject*> >::iterator it = m_HotkeyObjects.find(hotkey); | std::map<CStr, std::vector<IGUIObject*> >::iterator it = m_HotkeyObjects.find(hotkey); | ||||
if (it != m_HotkeyObjects.end()) | if (it != m_HotkeyObjects.end()) | ||||
for (IGUIObject* const& obj : it->second) | for (IGUIObject* const& obj : it->second) | ||||
{ | { | ||||
if (ev->ev.type == SDL_HOTKEYDOWN) | if (ev->ev.type == SDL_HOTKEYPRESS) | ||||
ret = obj->SendEvent(GUIM_PRESSED, EventNamePress); | ret = obj->SendEvent(GUIM_PRESSED, EventNamePress); | ||||
Done Inline ActionsPeriod after flag. elexis: Period after flag.
I guess it's not the kernel sending the keydown events. Not sure if it isnt… | |||||
Not Done Inline Actionsalready have the ticket #4915 bb: already have the ticket #4915 | |||||
Not Done Inline Actions
This statement can't be verified or corrected by only considering our code. elexis: > since the linux keyboard event manager sends the KEYDOWN only once.
This statement can't be… | |||||
Not Done Inline Actionsbb: https://github.com/SFML/SFML/issues/122 | |||||
else if (ev->ev.type == SDL_HOTKEYDOWN) | |||||
Not Done Inline Actions(The int conversion is needed because data2 is a void pointer and those should have a type before they are compared to an int?) elexis: (The int conversion is needed because `data2` is a void pointer and those should have a type… | |||||
Not Done Inline Actionsnot needed indeed bb: not needed indeed | |||||
Not Done Inline ActionsI actually don't know. Maybe clang or some other compiler complains. Should do what similar code does. elexis: I actually don't know. Maybe clang or some other compiler complains. Should do what similar… | |||||
Not Done Inline ActionsDo we use SFML as well I thought we only used SDL ? Stan: Do we use SFML as well I thought we only used SDL ? | |||||
Done Inline Actionswe use SDL indeed, but this is not an SDL issue, it most likely is a linux kernel issue bb: we use SDL indeed, but this is not an SDL issue, it most likely is a linux kernel issue | |||||
ret = obj->SendEvent(GUIM_KEYDOWN, EventNameKeyDown); | |||||
Done Inline Actions(\n?) elexis: (\n?) | |||||
else | else | ||||
ret = obj->SendEvent(GUIM_RELEASED, EventNameRelease); | ret = obj->SendEvent(GUIM_RELEASED, EventNameRelease); | ||||
Not Done Inline ActionsThis isn't consistent with global hotkeys. If we are passing an event name, why is the event always GUIM_PRESSED? wraitii: This isn't consistent with global hotkeys. If we are passing an event name, why is the event… | |||||
Done Inline ActionsInconsistency with globalhotkeys not introduced in this patch GUIM_PRESSED => I am stupid bb: Inconsistency with globalhotkeys not introduced in this patch
GUIM_PRESSED => I am stupid | |||||
} | } | ||||
} | } | ||||
else if (ev->ev.type == SDL_MOUSEMOTION) | else if (ev->ev.type == SDL_MOUSEMOTION) | ||||
{ | { | ||||
// Yes the mouse position is stored as float to avoid | // Yes the mouse position is stored as float to avoid | ||||
// constant conversions when operating in a | // constant conversions when operating in a | ||||
// float-based environment. | // float-based environment. | ||||
▲ Show 20 Lines • Show All 275 Lines • ▼ Show 20 Lines | assignment.erase( | ||||
std::remove_if( | std::remove_if( | ||||
assignment.begin(), | assignment.begin(), | ||||
assignment.end(), | assignment.end(), | ||||
[&pObject](const IGUIObject* hotkeyObject) | [&pObject](const IGUIObject* hotkeyObject) | ||||
{ return pObject == hotkeyObject; }), | { return pObject == hotkeyObject; }), | ||||
assignment.end()); | assignment.end()); | ||||
} | } | ||||
void CGUI::SetGlobalHotkey(const CStr& hotkeyTag, JS::HandleValue function) | void CGUI::SetGlobalHotkey(const CStr& hotkeyTag, const CStr& eventName, JS::HandleValue function) | ||||
{ | { | ||||
JSContext* cx = m_ScriptInterface->GetContext(); | JSContext* cx = m_ScriptInterface->GetContext(); | ||||
JSAutoRequest rq(cx); | JSAutoRequest rq(cx); | ||||
if (hotkeyTag.empty()) | if (hotkeyTag.empty()) | ||||
{ | { | ||||
JS_ReportError(cx, "Cannot assign a function to an empty hotkey identifier!"); | JS_ReportError(cx, "Cannot assign a function to an empty hotkey identifier!"); | ||||
return; | return; | ||||
} | } | ||||
// Only support "Press", "Keydown" and "Release" events. | |||||
if (eventName.empty() || (eventName != EventNamePress && eventName != EventNameKeyDown && eventName != EventNameRelease)) | |||||
{ | |||||
JS_ReportError(cx, "Cannot assign a function to an unsupported event!"); | |||||
return; | |||||
} | |||||
if (!function.isObject() || !JS_ObjectIsFunction(cx, &function.toObject())) | if (!function.isObject() || !JS_ObjectIsFunction(cx, &function.toObject())) | ||||
{ | { | ||||
JS_ReportError(cx, "Cannot assign non-function value to global hotkey '%s'", hotkeyTag.c_str()); | JS_ReportError(cx, "Cannot assign non-function value to global hotkey '%s'", hotkeyTag.c_str()); | ||||
return; | return; | ||||
} | } | ||||
UnsetGlobalHotkey(hotkeyTag); | UnsetGlobalHotkey(hotkeyTag, eventName); | ||||
m_GlobalHotkeys[hotkeyTag].init(cx, function); | m_GlobalHotkeys[hotkeyTag][eventName].init(cx, function); | ||||
} | } | ||||
void CGUI::UnsetGlobalHotkey(const CStr& hotkeyTag) | void CGUI::UnsetGlobalHotkey(const CStr& hotkeyTag, const CStr& eventName) | ||||
{ | { | ||||
if (m_GlobalHotkeys.find(hotkeyTag) == m_GlobalHotkeys.end()) | |||||
return; | |||||
m_GlobalHotkeys[hotkeyTag].erase(eventName); | |||||
if (m_GlobalHotkeys.count(hotkeyTag) == 0) | |||||
m_GlobalHotkeys.erase(hotkeyTag); | m_GlobalHotkeys.erase(hotkeyTag); | ||||
} | } | ||||
const SGUIScrollBarStyle* CGUI::GetScrollBarStyle(const CStr& style) const | const SGUIScrollBarStyle* CGUI::GetScrollBarStyle(const CStr& style) const | ||||
{ | { | ||||
std::map<CStr, const SGUIScrollBarStyle>::const_iterator it = m_ScrollBarStyles.find(style); | std::map<CStr, const SGUIScrollBarStyle>::const_iterator it = m_ScrollBarStyles.find(style); | ||||
if (it == m_ScrollBarStyles.end()) | if (it == m_ScrollBarStyles.end()) | ||||
return nullptr; | return nullptr; | ||||
▲ Show 20 Lines • Show All 829 Lines • Show Last 20 Lines |
This copies the string every time, which is rather unlucky for performance.
You can either go with a double-ternary, or a function returning a constant reference.
The double-ternary is probably easier, both compile to the same code anyways:
See https://godbolt.org/z/dI82LT