Skip to content

Enhance: get and set state of push-down-buttons (button love part1) #5227

Merged
SlySven merged 7 commits intoMudlet:developmentfrom
SlySven:Enhance_buttonLovePart1_addPushDownButtonStateGettersAndSetters
Jul 19, 2021
Merged

Enhance: get and set state of push-down-buttons (button love part1) #5227
SlySven merged 7 commits intoMudlet:developmentfrom
SlySven:Enhance_buttonLovePart1_addPushDownButtonStateGettersAndSetters

Conversation

@SlySven
Copy link
Copy Markdown
Member

@SlySven SlySven commented May 13, 2021

Brief overview of PR changes/additions

Provide a means to get and set the state of push down buttons (the latter without executing the associate command or script). It requires adding members to the TAction class to keep track of the EAction or TFlipButton instance that is the implementation of the button on a TEasyButton or TToolBar respectively. As it happens this showed that the previous code to regenerate them was creating new buttons each time but was not deleting the existing ones that were getting replaced.

Also:

  • made some members of the TAtion class (the name, script and both commands) private as otherwise there is no point in the setters and getters also provided!
  • simplified the existing getButtonState() {that only works within the script for a button) to remove an unneeded intermediate local (int) value.

Signed-off-by: Stephen Lyons slysven@virginmedia.com

Motivation for adding to Mudlet

It is something has been requested in the past (I think recently on Discord).

Other info (issues closed, discussion etc)

Further improvements to buttons/menus/toolbars are desirable and I can foresee some of them.

Release post highlight

Allow Lua scripts to get the state of click-down (toggle-able) buttons outside of the script for said button and allow for them to also set that state.

SlySven added 2 commits May 13, 2021 22:34
…art 1)

Provide a means to get and set the state of push down buttons (the latter
without executing the associate command or script). It requires adding
members to the `TAction` class to keep track of the `EAction` or
`TFlipButton` instance that is the implimentation of the button on a
`TEasyButton` or `TToolBar` respectively. As it happens this showed that
the previous code to regenerate them was creating new buttons each time but
was not deleting the existing ones that were getting replaced.

Also:
* made some members of the `TAtion` class (the name, script and both
commands) private as otherwise there is no point in the setters and getters
also provided!
* simpliedied the existing `getButtonState()` {that only works within the
script for a button) to remove an unneeded intermediate local (`int`)
value.

Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
The original comment was wrong as well - using a `Q_ASSERT_X` would have
broken things for a floatable/dockable toolbar type button (what
`TAction::mpFButton` will point at)...!

Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
@SlySven SlySven added enhancement needs documentation This pull request changes things the players would use/see and thus needs an update in the manual labels May 13, 2021
@SlySven SlySven added this to the 4.12.0 milestone May 13, 2021
@SlySven SlySven requested a review from a team as a code owner May 13, 2021 21:51
@SlySven SlySven requested review from a team May 13, 2021 21:51
@add-deployment-links
Copy link
Copy Markdown

add-deployment-links bot commented May 13, 2021

Hey there! Thanks for helping Mudlet improve. 🌟

Test versions

You can directly test the changes here:

No need to install anything - just unzip and run.
Let us know if it works well, and if it doesn't, please give details.

@github-actions
Copy link
Copy Markdown
Contributor

clang-tidy review says "All clean, LGTM! 👍"

SlySven added 2 commits May 30, 2021 15:10
Note that for the getter this is an intermediate stage as is should be
possibble to combine it with the existing `getButtonState()` function that
takes NO arguments but only works within the Lua script for a push-down
button.

Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
This simpilifies the UI so that `getButtonState()` works the same as
before but if an button's ID number or "name" is supplied as an argument
the state of the corresponding button (as a boolean though, NOT the
existing and, TBH, odd, integer value 1 or 2, that the original function
produces) is returned. In the event that the matching item is NOT a
push-down button, or that it does not match an existing button then a 'nil'
+ (run-time) error message is returned instead.

Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
@SlySven SlySven modified the milestones: 4.12.0, 4.13.0 May 30, 2021
Copy link
Copy Markdown
Member

@keneanung keneanung left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One suggestion for me, but otherwise I like this.

Comment on lines +5793 to +5821
auto argType = lua_type(L, 1);
TAction* pItem = nullptr;
if (argType == LUA_TNUMBER) {
int id = lua_tonumber(L, 1);
if (id < 0) {
return warnArgumentValue(L, __func__, QStringLiteral("item Id (%1) invalid, it must be equal or greater than zero").arg(id).toUtf8().constData());
}
pItem = host.getActionUnit()->getAction(id);
if (!pItem) {
return warnArgumentValue(L, __func__, QStringLiteral("no button item with Id %1 found").arg(id).toUtf8().constData());
}
if (!pItem->isPushDownButton()) {
return warnArgumentValue(L, __func__, QStringLiteral("item Id with %1 is not a push-down button").arg(id).toUtf8().constData());
}
}

if (argType == LUA_TSTRING) {
QString name = lua_tostring(L, 1);
if (name.isEmpty()) {
return warnArgumentValue(L, __func__, "item name must not be an empty string");
}
pItem = host.getActionUnit()->findAction(name);
if (!pItem) {
return warnArgumentValue(L, __func__, QStringLiteral("no button item with name '%1' found").arg(name).toUtf8().constData());
}
if (!pItem->isPushDownButton()) {
return warnArgumentValue(L, __func__, QStringLiteral("item with name '%1' is not a push-down button").arg(name).toUtf8().constData());
}
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This whole part seems to be pretty much the same as in the set function. I would suggest putting this into a function that's used by both.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TBH if the code was to be used in more than these two cases I'd go along with that idea but the additional complexity of a further function call for just this pair means I think it is a borderline decision and I'd prefer not to do that currently...

Copy link
Copy Markdown
Member Author

@SlySven SlySven Jul 3, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔

In the medium term I'd like to have a set of introspection (?) functions that can get, and for some set, the common elements of all the mudlet item types (alias, button/menu/toolbars, keybindings, scripts, timers, triggers) i.e. "name", "command", "ID", "active" {based on both it's own and its ancestors' state} and possibly some further details... as such it may then be useful to factor out item identification based on EITHER a numeric ID OR a string name basis. At that point this would be useful to revisit.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To me, this is not a borderline decision. It has strings and quite a bit of logic that should stay the same. And the easiest way for that is adding a function.

@Kebap Kebap changed the title Enhance: (button love part1) add push down button state getters and setters Enhance: get and set state of push-down-buttons (button love part1) Jun 25, 2021
Copy link
Copy Markdown
Contributor

@Kebap Kebap left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • setButtonState is missing in Area 51

set the state of push down buttons (without executing the associate command or script).

Is that really always desired? Maybe a toggle would make sense. Not sure if this should even be default. Then again, I hardly used buttons myself.

return warnArgumentValue(L, __func__, QStringLiteral("no button item with Id %1 found").arg(id).toUtf8().constData());
}
if (!pItem->isPushDownButton()) {
return warnArgumentValue(L, __func__, QStringLiteral("item Id with %1 is not a push-down button").arg(id).toUtf8().constData());
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return warnArgumentValue(L, __func__, QStringLiteral("item Id with %1 is not a push-down button").arg(id).toUtf8().constData());
return warnArgumentValue(L, __func__, QStringLiteral("item with Id %1 is not a push-down button").arg(id).toUtf8().constData());

we discussed earlier if we go for "id" or "Id" or "ID" and can't remember the consensus reached.. but I feel like "Id" is the worst of those ☹️

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Um, one reference might be: #2605 - and it has not been closed...

Tomayto, Tomaahtoe ....

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I'll revise it to ID and hope that'll silence the critics... 🤞


if (!pItem) {
// we'll get here if the (first) argument is NOT usable:
lua_pushfstring(L, "%s: bad argument #1 type (ID as number or name as string expected, got %s!)",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See there is an "ID", let's use that consistently, shall we?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, in the scheme of things I can't be arsedbothered to fight this...

@SlySven
Copy link
Copy Markdown
Member Author

SlySven commented Jul 3, 2021

set the state of push down buttons (without executing the associate command or script).

Is that really always desired? Maybe a toggle would make sense. Not sure if this should even be default. Then again, I hardly used buttons myself.

When configuring a UI that uses buttons/menus/toolbars it is pretty much essential to be able to set the state of push-down buttons to a required initial or to reflect something that is happening in-game independently of whatever script/command is associated with that button. A bit of refactoring to make the Lua script a simple function call to a script defined elsewhere (in a script element I guess) would be enough to reproduce clicking the button whereas only providing a function to simulate toggling the button state AND executing the script / send the command is actually a much less flexible way of doing things - and would not give the same scope for usage that the setter function herein gives...

SlySven added 2 commits July 3, 2021 20:32
As suggested by peer-review.

Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
…e(...)

This was strongly requested by @keneanung though my preference was against
it for just two instances - as developing an API that would work with the
`warnArgumentValue(...)` function took a bit of thought and I had to work
with handling a `TAction**` (pointer to a pointer to a `TAction`) as a
function argument!

Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
Copy link
Copy Markdown
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

Copy link
Copy Markdown
Member

@keneanung keneanung left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you very much for the rework 😄 I have a niggle that I'd love to see a change for. But it won't break my heart if you're adamant here 😉

// it also resets the pItem to be a nullptr
// does NOT return (normally) if the index item on the stack is not a number or
// a string
int TLuaInterpreter::getTActionFromIdOrName(lua_State* L, TAction** pItem, const int index, const char* func)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this isn't atypical for C++, but I prefer using function arguments as input instead of output. This is also mentioned in Clean Code. Have you considered returning multiple values via https://www.geeksforgeeks.org/returning-multiple-values-from-a-function-using-tuple-and-pair-in-c/?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree - and we have many examples of this, check for example:

    std::pair<bool, QString> changeModuleSync(const QString& enableModuleName, const QLatin1String &value);
    std::pair<bool, QString> getModuleSync(const QString& moduleName);

Make it a std::pair with the original return value of
`TLuaInterpreter::getTActionFromIdOrName(...)` instead of passing it as a
non-const reference argument.

Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
Copy link
Copy Markdown
Member

@vadi2 vadi2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding this requested feature in!

@SlySven SlySven merged commit 0c348f6 into Mudlet:development Jul 19, 2021
@SlySven
Copy link
Copy Markdown
Member Author

SlySven commented Jul 19, 2021

📚 documentation done, see:

@vadi2
Copy link
Copy Markdown
Member

vadi2 commented Jul 20, 2021

Looks good! But it should be in Area 51 as it's not available yet. People naturally get confused when we list releases in docs that aren't out yet

@Kebap
Copy link
Copy Markdown
Contributor

Kebap commented Jul 20, 2021

Please honor Area 51 template, e.g. don't hide version info below example section

@SlySven
Copy link
Copy Markdown
Member Author

SlySven commented Jul 20, 2021

Looks good! But it should be in Area 51 as it's not available yet. People naturally get confused when we list releases in docs that aren't out yet

Ah, I was thinking that it being in the PTB would be justification for it making it into the main documentation.

Please honor Area 51 template, e.g. don't hide version info below example section

🤔 I was trying to avoid contaminating the auto-completion extraction process scraper.

Anyhow I have now relocated them, in the meantime, to Area 51 and perhaps someone else could reshape the items so as to fit better...

@SlySven SlySven deleted the Enhance_buttonLovePart1_addPushDownButtonStateGettersAndSetters branch July 22, 2021 21:35
@Kebap
Copy link
Copy Markdown
Contributor

Kebap commented Sep 20, 2021

perhaps someone else could reshape the items so as to fit better...

someone else did

@Kebap
Copy link
Copy Markdown
Contributor

Kebap commented Sep 20, 2021

📚 documentation done, see:

* ~**[getButtonState(...)](https://wiki.mudlet.org/w/Manual:Mudlet_Object_Functions#getButtonState)**~ - pulled from main Wiki

* ~**[setButtonState(...)](https://wiki.mudlet.org/w/Manual:Mudlet_Object_Functions#setButtonState)**~ - pulled from main Wiki

* **[getButtonState(...)](https://wiki.mudlet.org/w/Area_51#getButtonState)** - relocated to Area 51

* **[setButtonState(...)](https://wiki.mudlet.org/w/Area_51#setButtonState)** - relocated to Area 51

published again for upcoming release

@Kebap Kebap removed the needs documentation This pull request changes things the players would use/see and thus needs an update in the manual label Sep 20, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants