Enhance: allow modification of the player room indication on 2D map#2621
Conversation
This commit reorganises the 2D Painter code to draw the player room indicator AFTER all the rooms have been drawn so that it does not get overdrawn by rooms painted after the player's room - which it could be if the rooms are at maximum size or the area is in "gridMode". It also offers some alternative marker options in the form of an oversized ring around the room which reduces the obstruction of the details of the room when the marker is drawn on it. The alternatives are: * a fixed red colour ring * a fixed blue/yellow colour ring - two contrasting colours mean that it can not be lost if drawn over a room that already has one of them as its colour (environment) setting. * a customizable two colour ring where the user can set the outer and inner colours as they like - even to the same colour. This commit does not contain code to save the setting between sessions. It is intended to get peer/public evaluation of the proposal. A follow up commit will be appended if this proposal is acceptable and does work. The ancient `(bool) Host::mMapStrongHighlight` option is still respected, I note that it was introduced in 3cb1719 from 2011/01/20 (after Mudlet 1.0.5) and the code to control it was lost in 8b0e8bb from 2012/12/31 "NEW Vadim Peretokin: mapper remembers settings" just before the release of Mudlet 2.0...! Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
|
Hey there! Thanks for helping Mudlet improve. 🌟 Test versionsYou can directly test the changes here:
No need to install anything - just unzip and run. |
|
I have a different take on doing this - what if we allow people to set a custom image in place of the marker? That would be way more flexible than the current and proposed ring system, yet still relatively easy to code and for people to use. |
|
This seems like a good change. I'm a little concerned the ring is too large, as it covers up adjacent rooms just slightly (and their exits), but it's a large step in the right direction. As for a custom image @vadi2 - I'm not so sure. The idea of sailing the internet just to find an image to replace the marker that I don't like doesn't seem enticing to me. |
|
Also you would also need an image with a degree of transparency - and I do not imaging that there is a large proportion of stock images with that characteristic - remember |
A (couple of) spin-box(es) to set the outer (and inner) diameters might help there but you, Vadim, have previously reminded us to be really careful about adding more knobs and switches... 😟 |
|
Yeah, perhaps not on the general settings screen but hide the very rarely-used options behind pop-up menu. I don't foresee too many customising this given how few have asked to change it over the years. |
Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
|
Well I've added controls to set the size and also added alpha (transparency) controls to the custom colours which means that it can be adjusted to NOT obscure details - though what those might be can vary I guess between users' preferences for maps. For instance grid mode maps perhaps will have different requirements than those with exits and where there is at least one (or two) room spaces between adjacent rooms - that is why I doubt there is one setting that everyone will think is the best... |
|
👍 |
vadi2
left a comment
There was a problem hiding this comment.
I like 👍 thanks for adding this!
|
It is still a Work-honestly-In-my-Plans-even-yesterday (WhImPey)... 😁 - it needs the settings to be save/loaded between session... ... also I would like to try and find a way to draw the player room last so then I can put it back to where it was before but avoid other rooms being painted from overwriting the new stuff. The quick and dirty fix would be to convert the |
|
Hm... yes, let's just paint the room on top after instead of keeping changing the datastructures we use a lot. |
|
Actually the refactoring isn't too bad and it does allow the |
|
Oh, b****r - I had two parallel repositories (so I can run side by side comparisons of my work in progress code against the main line one) both open in Qt Creator - and I did the refactoring on the wrong repository's code! 🤦♂️ |
This is done by extracting the relevant room drawing code to a separate inline function that is used whilst iterating through the area rooms to paint them, skipping but noting if the player room is found and then that function is used to paint the player's room afterwards. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
|
It turns out that using |
|
Good to know! |
|
I'll see if I can fix it this morning - whilst on a 2 hour train to pick up a replacement 🚗 from a parent - I've reserved a Window seat with a table so should have power and WiFi on the way... 😀 |
The clang compiler does not like `auto` being used as a type in function prototypes as it is not formally part of the C++14 standard but a GCC extension - it got put in by the Qt Creator function extraction code option on the refactor menu. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
| // player's room and then, AFTER all those have been drawn, once for the | ||
| // player's room if it is visible. This is so it is drawn LAST (and any effects, | ||
| // or extra markings for it do not get overwritten by the drawing of the other | ||
| // rooms)... |
There was a problem hiding this comment.
I don't think this comment is needed. We don't need the history of the code as a comment (we can look at git history for that) and we can tell the function is used in two places by looking at usages. Long comments don't really help in readability, plus it's only you who'd be interested in keeping it up to date...
There was a problem hiding this comment.
Well, not every usage of the source code is going to be from a git repository, but I take your point - how about if I reduced it to a one-liner along the lines of:
// We need to ensure the player's room is drawn last so that any oversized parts of it don't get overwritten by other rooms....
There was a problem hiding this comment.
Perfect, and that should be at the point where this function is called for that reason - not at the function definition (doesn't make sense there)
| bool __Pick = mPick; | ||
| // As it happens this local is never changed in this method so it can be | ||
| // made const: | ||
| const bool __Pick = mPick; |
There was a problem hiding this comment.
| const bool __Pick = mPick; | |
| const bool pick = mPick; |
There was a problem hiding this comment.
Agreed! Whoever thought to using a double leading underscore is heading for trouble as far as I can see, e.g. https://stackoverflow.com/questions/224397/why-do-people-use-double-underscore-so-much-in-c - mind you, I think I have used them in the qmake project file but then that is not text that is parsed by the compiler/linker...
Not the final version yet I am afraid - got to get "saving-to" and "loading-from" the game saves working and it is a bit awkward as the <ASIDE>This means the settings have to be stored in the |
They are saved with the profile's data rather than the map. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
|
Okay - finally got the save and load working. Can you okay this now @vadi2 ? Helpful hint no. 42: using The moral of this is - if adding a new attribute to one of the elements that are exported in an Mudlet |
vadi2
left a comment
There was a problem hiding this comment.
Works well but I think there are improvements we can make to the code it make it less confusing, see below.
src/Host.h
Outdated
| // An invalid/null value is treated as the "show all"/inactive case: | ||
| QTime mTimerDebugOutputSuppressionInterval; | ||
|
|
||
| // This hold copies of variables from the TMap class which are saved with |
There was a problem hiding this comment.
This is a confusing comment and we shouldn't have it - it's the Host class that stores the application settings in Mudlet. Other classes should reference Host for the settings they need, not the other way around.
There was a problem hiding this comment.
It didn't evolve like that! When I started this PR I hadn't contemplated the load/save of the settings - though in hindsight that comment does need revision..
src/Host.h
Outdated
| QColor mPlayerRoomColorPrimary; | ||
| QColor mPlayerRoomColorSecondary; | ||
| // Mode selected - 0 is closest to original style: | ||
| quint8 mPlayerRoomStyle; |
There was a problem hiding this comment.
Why such an esoteric datatype choice?
See C++ Core Guidelines:
http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#es106-dont-try-to-avoid-negative-values-by-using-unsigned
There was a problem hiding this comment.
Deliberate limit on something with less than a handful of choices (four), and it is much safer to convert between integer representations of numbers of different bitnesses for unsigned integers.
There was a problem hiding this comment.
This seems to go exactly against the best practice mentioned above?
| // player's room and then, AFTER all those have been drawn, once for the | ||
| // player's room if it is visible. This is so it is drawn LAST (and any effects, | ||
| // or extra markings for it do not get overwritten by the drawing of the other | ||
| // rooms)... |
There was a problem hiding this comment.
Perfect, and that should be at the point where this function is called for that reason - not at the function definition (doesn't make sense there)
src/T2DMap.cpp
Outdated
| // player's room if it is visible. This is so it is drawn LAST (and any effects, | ||
| // or extra markings for it do not get overwritten by the drawing of the other | ||
| // rooms)... | ||
| inline void T2DMap::drawRoom(QPainter& painter, QFont& roomVNumFont, QPen& pen, TRoom* pRoom, TArea* pArea, const int currentRoomId, const bool isFontBigEnoughToShowRoomVnum, const int playerRoomId, const float rx, const float ry, const bool picked) |
There was a problem hiding this comment.
This function signature is a monster with many tentacles: I think if we gave anyone drawRoom(painter, roomVNumFont, pen, room, pArea, currentAreaRoom, isFontBigEnoughToShowRoomVnum, playerRoomId, rx, ry, __Pick); to look at, they'd have no clue what they were looking at. Let's improve it!
Can't currentRoomId be derived from pRoom inside the function? Or something like that - we have 3 arguments that all talk about the room, at least one should go.
pArea is only checked for gridMode - that should be passed in as a boolean to make the function interface more intuitive.
isFontBigEnoughToShowRoomVnum - no to yoda speak and 30 character variables! roomTextfits would work fine, observe:
if (mShowRoomID && roomTextfits) {And it wouldn't even need the comment it has right now, because it would be self-explanatory.
There was a problem hiding this comment.
The many tentacles come from me using the refactor code to extract a large chunk of code from the paintEvent code but not spending enough time to refine out all the extraneous bits - the use of pArea to get the gridmode setting does sound sensible, getting currentAreaRoom from pRoom also; roomTextFits though - what text - there is a symbol is that the text it means - fair enough I will have a think on that and find something we both can agree on...
There was a problem hiding this comment.
😟 Oh, I haven't done much with this. Lemme have another look at it...
There was a problem hiding this comment.
... okay take a look at the latest commit: 010f8b4 !
src/T2DMap.cpp
Outdated
| if (mpMap->mpRoomDB->getRoom(mTarget)) { | ||
| mpMap->mTargetID = mTarget; | ||
| if (mpMap->findPath(playerRoomId, mpMap->mTargetID)) { | ||
| mpHost->startSpeedWalk(); |
There was a problem hiding this comment.
Why is the function to draw a single room on a map calling startSpeedWalk()? That doesn't seem to make sense. Need to fix this in a follow-up PR.
There was a problem hiding this comment.
ℹ️ Nope, that is actually starting the speed walk route calculation - because the current room being painted has been determined to be close enough to where the mouse was double-clicked on the map to be the destination for the speed walk. Incidentally the use of the playerRoomId is because that is the starting point for the speed walk route. Also, the destination room for the speedwalk gets drawn with a red-circle on it for just that one paint event.
There was a problem hiding this comment.
As part of the previous point #2621 I happened to refactor this code out to a separate initiateSpeedWalk(...) helper! 👼
src/TMap.cpp
Outdated
|
|
||
| void TMap::initialiseMembersFromHost() | ||
| { | ||
| mPlayerRoomColorPrimary = mpHost->mPlayerRoomColorPrimary; |
There was a problem hiding this comment.
Why are we copying that into this class?
There was a problem hiding this comment.
I originally wrote the code on the basis of having the settings in the TMap class - because they are associated with the map strangely enough 😉 - but then I worked out that they would need to be stored as part of the profile and thus as part of the Host class. I am aware that some of the members of that class are protected by a QMutex but it is not entirely clear why those particular ones are so protected; and rather than having to read the settings from that class for every T2DMap::paintEvent() I felt it was safer to work from copies held in the TMap class and only access the master ones in Host when they needed to be changed or used to initialise the copies.
There was a problem hiding this comment.
You're the one who put a QMutex on them... if we don't need it anymore, lets take it off?
Seems to make sense not to complicate things with forgotten mutexes and then copying things around...
| void dlgProfilePreferences::slot_setPlayerRoomSecondaryColor() | ||
| { | ||
| Host* pHost = mpHost; | ||
| if (!pHost || !mpHost->mpMap || !mpHost->mpMap->mpMapper || !mpHost->mpMap->mpMapper->mp2dMap) { |
There was a problem hiding this comment.
This setting should be adjustable even when the map isn't open, right?
There was a problem hiding this comment.
Debatable, I think. After all why show the controls if you are Mudding without a map - I know I wouldn't but not everyone thinks like that...
There was a problem hiding this comment.
Well - because you haven't yet opened the map?
There was a problem hiding this comment.
Ah, looking at how the code is structured that slot directly alters the 2D mapper by calling a method in the T2DMap class - which can't happen if there is no map loaded. Going to have to rethink this...
…odificationOfPlayerRoomIndicatorOn2DMap
|
@SlySven ping |
|
👋 :) |
As the `TMap` members being initialised are (now) public they can assigned values from the Host members they are caching directly in the `mudlet::createMapper(...)` method. In that method - since there are many uses of `(TMap*) pHost->mpMap` it is sensible to create a shorter named variable `pMap` to hold that pointer value. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
…IndicatorOn2DMap Conflicts resolved in: * src/Host.cpp * src/Host.h * src/T2DMap.cpp * src/T2DMap.h * src/dlgProfilePreferences.cpp * src/dlgProfilePreferences.h * src/mudlet.cpp Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
They were only being written to the cached values in the TMap instance so were not being stored when the profile was saved. Also the default output from `QColor::name()` does NOT contain any alpha component so that was not being stored either when the profile was being saved. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
It is not possible to just colour the background of the `QPushButton`s that set the custom colours to use for the *custom* player room marker as the transparency effects do not show. Instead this commit arranges for an icon with a black-and-white checker board pattern is over-painted with a brush in the relevant colour so that when the opacity is less than 100% the pattern is shown to an extent which is proportional to the degree of transparency of the colour chosen. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
vadi2
left a comment
There was a problem hiding this comment.
Works well! I love the realtime feedback so you can do the settings adjustment quicker.
… code Suggested in peer review comment: Mudlet#2621 Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
…alised Forgot this when I was producting Mudlet#2621 as I tend to use the other form of the map in a floating/dockable window. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
…alised Forgot this when I was producting #2621 as I tend to use the other form of the map in a floating/dockable window. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
…udlet#2621) This is a squash-and-merge of a number of commits with the following edited summary: This PR reorganises the 2D Painter code to draw the player room indicator AFTER all the rooms have been drawn so that it does not get overdrawn by rooms painted after the player's room - which it could be if the rooms are at maximum size or the area is in "gridMode". It also offers some alternative marker options in the form of an oversized ring around the room which reduces the obstruction of the details of the room when the marker is drawn on it. The alternatives are: * a fixed red colour ring * a fixed blue/yellow colour ring - two contrasting colours mean that it can not be lost if drawn over a room that already has one of them as its colour (environment) setting. * a customizable two colour ring where the user can set the outer and inner colours as they like - even to the same colour. The ancient `(bool) Host::mMapStrongHighlight` option is still respected, I note that it was introduced in 3cb1719 from 2011/01/20 (after Mudlet 1.0.5) and the code to control it was lost in 8b0e8bb from 2012/12/31 "NEW Vadim Peretokin: mapper remembers settings" just before the release of Mudlet 2.0...! Refactor: ensure player room is drawn last This is done by extracting the relevant room drawing code to a separate inline function that is used whilst iterating through the area rooms to paint them, skipping but noting if the player room is found and then that function is used to paint the player's room afterwards. Revise: made code acceptable to all compilers The clang compiler does not like `auto` being used as a type in function prototypes as it is not formally part of the C++14 standard but a GCC extension - it got put in by the Qt Creator function extraction code option on the refactor menu. Revise: allow player room marking customisation to be saved and restored They are saved with the profile's data rather than the map. Revise: show transparency effects in custom player room marker colours It is not possible to just colour the background of the `QPushButton`s that set the custom colours to use for the *custom* player room marker as the transparency effects do not show. Instead this commit arranges for an icon with a black-and-white checker board pattern is over-painted with a brush in the relevant colour so that when the opacity is less than 100% the pattern is shown to an extent which is proportional to the degree of transparency of the colour chosen. Refactor: extract code to start 2D map speed-walk & simplify drawRoom code Suggested in peer review comment: Mudlet#2621 Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
…alised Forgot this when I was producting Mudlet#2621 as I tend to use the other form of the map in a floating/dockable window. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>





This commit reorganises the 2D Painter code to draw the player room indicator AFTER all the rooms have been drawn so that it does not get overdrawn by rooms painted after the player's room - which it could be if the rooms are at maximum size or the area is in "gridMode".
It also offers some alternative marker options in the form of an oversized ring around the room which reduces the obstruction of the details of the room when the marker is drawn on it. The alternatives are:
This commit does not contain code to save the setting between sessions. It is intended to get peer/public evaluation of the proposal.A follow up commitwill behas been appendedifas this proposal is acceptable and does work.The ancient
(bool) Host::mMapStrongHighlightoption is still respected, I note that it was introduced in 3cb1719 from 2011/01/20 (after Mudlet 1.0.5) and the code to control it was lost in 8b0e8bb from 2012/12/31 "NEW Vadim Peretokin: mapper remembers settings" just before the release of Mudlet 2.0...!This may fix #2057 raised by @Eraene .
Signed-off-by: Stephen Lyons slysven@virginmedia.com