Page MenuHomeWildfire Games

Map browser for gamesetup
Needs ReviewPublic

Authored by nani on Dec 23 2018, 11:49 PM.

Details

Reviewers
elexis
Group Reviewers
Restricted Owners Package(Owns No Changed Paths)
Summary

Would be nice to see all maps previews in a single page and be able to select or just see them.

Test Plan

See that everything works "just right"

Diff Detail

Repository
rP 0 A.D. Public Repository
Branch
/ps/trunk
Lint
Lint OK
Unit
No Unit Test Coverage
Build Status
Buildable 11102
Build 19750: arc lint + arc unit

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes
elexis added inline comments.Feb 4 2020, 1:00 PM
binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/Controls/MapsGrid.js
1 ↗(On Diff #11226)

This is the same class as the closebutton.

binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/Controls/SelectButton.js
9

Better a custom onPress function that will write to g_GameAttributes, and then calling closePage as usual.

binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/Controls/ZoomInButton.js
9

translate(this.action) is not sufficient to translate the string, unless the string is wrapped in a markForTranslation call (otherwise the python script wont extract the untranslated string).

MouseWheelDown is not a string that should be translated, but either we use the same currently untranslated method of displaying key-combinations assigned to hotkeys, or use a proper english string, not a C++ GUI object event name (i.e. perhaps translate("Mouse Wheel Down") or whatever is correct according to en-US).

Intro.txt has these translated strings:

Shift + Mouse Wheel Rotate Up – Rotate camera clockwise around terrain
Shift + Mouse Wheel Rotate Down – Rotate camera counter-clockwise around terrain

(If we go with the consistent but untranslated means, it would be a case for colorizeHotkey, but that actually doesn't work without modification since it currently only supports hotkeys, not assigned key combinations)

(It's somewhat inconsistent that the tooltip stating that mousewheel can be used to scroll is on the page is not on the page but on a button that doesn't perform the action / usually it's on the same object)

binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MapBrowserPage.js
5

(wrong semicolon)

49

The onMouseWheelUp / Down logic seems more specific to the GridBrowser, and the GUIObject instance already is passed to the GridBrowser.

51

(Look like this.gridBrowser.generateGrid();` call shoudl be in the gridbrowser ctor)

54

I guess this is in there to debug. Or if its in there as a feature by design, then it should only be done if g_IsControler, and not on hotload I suppose (since in the other two cases the map had already been selected).

57

getMapsOfTypeFilter is only used four times with gridBrowser.setList and never otherwise, so it can be merged.

I so far had bad experience with default arguments, since someone reading no arguments being passed usually expects no arugments to be passed. But if the reader sees that an argument is passed, he will know the argument before looking up the functions code. Also the arguments never change, so the arguments can be removed here.

64

The maptype should not be stored in the map.

88

childFunction(child, childIndex, map, mapIndex) does things a constructor typically does, and separating it from the Page controler would allow to extend child functionality outside of the child constructor function. () => could become replaceable / overridable / modifiable / inherited prototype functions of the child class.

109

dead line of code? onOver isn't an event name that is ever tiggered, is it? I can't find it in source/gui/
By using a class one can be stored in the child class instance.
(C++ GUI should warn about that unless one wants to use it as some sort of hack to store functions in event handler of events that dont exist)

121

The select function hardcodes what happens when the select event is triggered, but instead every of these GUI objects or logical sets of GUI objects (mapdescription objects, selectButton) could be represented by a class that subscribes to the onSelect event (or onFooChange), thus become decoupled from each other. Mods or new features of the MapBrowserPage could then just subscribe to the event as well without having to modify existing code.

161

(Zoom values and logic can be split into a separate class.)

175

Using an event message onOpenPage allows for decoupling and de-hardcoding the event subscribers.

The assigned nextPage previousPage hotkeys are an assignmet of the NextPageButton and PreviousPageButton, so this logic piece should be located there.

189

// Get maps, go to current gamesetup map and simulate a selection this specifies not few logic of the grid browser, so it should be moved to a gridbrowser function. Can be done with an onOpenPage handler too for instance.

202

Engine.GetGUIObjectByName("mapsSearchBox") occurs in two different files. Ideally every object is referred to and owned by one handler, so it becomes more obvious which handler class has the control / responsibility over a GUI object (the other classes operating on that GUI object then should go through some event-subscription interface to avoid the shotgun antipattern).

215

The first size is constant / static / not modified by the class instance, so it sounds like a prototype property, but the other width is dependent on the current user selection, which mgiht warrant storing it in two different objects.

Though min&max arent modified by the class instance, only value, which would also warrant having min/max on the prototype and the zoom.value on the instance, most easily directly. (this.mapZoom.scale.value -> this.selectedZoom)

binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MapBrowserPage.xml
23

Current convention is that GUI Object names start with lowercase.

69

+ / - string should really have translation context where possible

86

"previewSelectedOverlay" is a dead object?

binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MapBrowserSearchBox.js
1 ↗(On Diff #11226)

Don't see why this isn't in the MapBrowserPageControls object along the other objects. Moving it there allows the Page to become agnostic of this object / remove the hardcoded ownership.

5 ↗(On Diff #11226)

MapBrowserPage -> mapBrowserPage (current convention is starting with capital where the classname is meant or a prototype property meant)

9 ↗(On Diff #11226)

this.mapsSearchBox = Engine.GetGUIObjectByName("mapsSearchBox");, at least thats the current convention (to specify the GUIObjectName in the constructor if its a globally unique object)

33 ↗(On Diff #11226)

In SearchBox, the map labels are translated and then sent to the GridBrowser, but the other calls dont translate.

nani added inline comments.Feb 4 2020, 2:34 PM
binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/Controls/CloseButton.js
7

If we want to make this class modable we must leave a reference of the parent page no?

binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/Controls/MapsGrid.js
1 ↗(On Diff #11226)

This class was supposed to be on the diff (as you can see is unfinished and not used)

binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MapBrowserPage.js
51

generateGrid is probably the most expensive call of the gridbrowser class itself and should only be called when needed (e.g opening the page or on window resize)

54

Yes. Debug.

64

Why not?

109

Dead code.

binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MapBrowserPage.xml
86

Left it untouched given I might had use it for it later on.

binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MapBrowserSearchBox.js
33 ↗(On Diff #11226)

The translation is only to compare against the given input caption.

Nescio added a subscriber: Nescio.Feb 4 2020, 5:39 PM

A few remarks on the image from the summary:


Could you add a scrollbar (yellow)? I dislike the previous and next page buttons (magenta).
What do the plus and minus buttons (cyan) do? And why are they placed at that exact spot? Also, could you use a proper minus sign (−, which has a width and centre equal to +), instead of the ordinary hyphen (which tends to be visibly much shorter)?

Nescio added inline comments.Feb 4 2020, 5:41 PM
binaries/data/config/default.cfg
298

Why not just "M"?

elexis added a comment.Feb 4 2020, 5:49 PM

A few remarks on the image from the summary:


Could you add a scrollbar (yellow)? I dislike the previous and next page buttons (magenta).

Scrollbar support has not been implemented yet, otherwise it should be used in the structree.
nani has some JS scrollbar implementation, but as far as I know it should be implemented in C++ (for example for performance, duplication avoidance, consistency with the other gui object code and existing scrollbar code).

What do the plus and minus buttons (cyan) do?

Increase the size of the mappreview images in the grid

Also, could you use a proper minus sign (−, which has a width and centre equal to +), instead of the ordinary hyphen (which tends to be visibly much shorter)?

Y

binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MapBrowserSearchBox.js
4 ↗(On Diff #11226)

whitespace -> tabs instead of spaces

40 ↗(On Diff #11226)

goToPage(0) is redundant, already done in setList

elexis added a comment.Feb 8 2020, 2:34 PM

New classes:

  • GridBrowser class (D1650) split from MapGridBrowser class to keep it more reusable.
  • GridBrowserItem and MapGridBrowserItem class, so that one may keep references, a local state, register events to handlers and specify functions per item (instead of only one function doing all of that locally).

What do the plus and minus buttons (cyan) do?

One could also implement a slider (perhaps this again should use discrete step values D406 beforehand)

  • To avoid the unused space and horizontal centering, it will be better to have the zoom level specify the number of columns. So will change that zoom mechanics too.
  • I see more cases against than for imprecise pattern matching like "lol" yielding "Lorraine Plaine".
  • Child renamed to Item, at least a Grid where one can select one of those children/items seems more intuitively to be made out of Items to me - similar to a dropdown that has a list of items.
binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/Controls/FilterDropdown.js
27 ↗(On Diff #11226)

Either we can assume that the "all maps" filter exists, and thus always one item returned, or we assume !filters can happen in a use case we want, then the dropdown should become hidden in that case.
Currently, getAvailableMapFilters always returns an array (but it can return an empty array, which is not what is checked here).

41 ↗(On Diff #11226)

consistent return values https://eslint.org/docs/rules/consistent-return

return foo.list[selected] || default;

binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/Controls/ZoomInButton.js
14

I suggest and implement to disable the prev/next button if the end has been reached, instead of jumping to the other end. That's the more familiar behavior to me, and close to the actual button caption "previous" and "next".

18

The MouseWheel tooltip should really be moved to the GUI object that has the MouseWheel action assigned, otherwise it will mislead the reader to assume the action happens when hovering the buttons while scrolling.

binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/GridBrowser.js
4

("boxed-like" -> aim for precise and complete definitions. If I see "boxed-like", I wonder what the difference to boxed-like without quotes is. I suppose the actual restriction is image objects or GUI objects that have a sprite property)

31

The gridbrowser doesnt use the list array except for its length property.
Therefore the GridBrowser would be more versatile and concise if it would only use a this.childrenCount length member property instead of an array list and have the user of the grid browser implement the list logic.

43

clampIndex seems to add code to hide hypothetical code errors, but code errors should be reported, not hidden.
(So removing the function will do more for that objective, because the developer running into the case will be alarmed instead of not notice the issue.)

60

(This clamp call also is covering up an input error, but that input error either never happens or it does happen and its hidden from the developer)

86

This computation can be done when nColumns / nRows is changed.

91

Math.max(1, seems unneeded (hiding an error)

126

if isSelectedInPage then goToPageOfSelected is the same as goToPage(currentPage).

(If I understand this if-else statement correctly, when resizing the window, the page will be selected that shows the first item of the page in the version of the page just before the resize event.)

140

Not sure if it should hardcode horizontal centering. Or it it does that, use 50% size +/- offset.

binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MapBrowserPage.js
139

map.Description is already stored and translated, at least the one returned by the MapFilters class.

binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MapBrowserPage.xml
21

Missing label for the text search filter

63

maptype/mapfilter labels should be in the same gui object parent as mapfilter/maptype dropdown

89

70+330+10-30=380

binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MapBrowserSearchBox.js
27 ↗(On Diff #11226)

(redundant .toLowerCase() )

33 ↗(On Diff #11226)

mapFilters and getMapsOfTypeFilter already return translated map names, so there are translate calls that are wrong (translating an already translated string)

elexis added a comment.Feb 8 2020, 3:03 PM
  • Item-Description: Should(n't) the map description be shown (maybe 3-5 lines + scrollbar) below the mappreview thumbnail, so that the player can make a more informed decision / comparison of maps? In fact the height of the description could vary, so that the unused vertical space would disappear as well (at the cost of perhaps one or two rows depending on zoom level)
  • Status-Bar: Should(n't) it display the "prev/next" + page counter data below the items in a status bar? (It could also display item count)
  • The mapbrwserpage button looks weird, we considered making this a regular button.
binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/Controls/FilterDropdown.js
17 ↗(On Diff #11226)

list assignments can happen in only one function of the code to avoid duplication.
getAvailableMapFilters call + argument is duplicated too

binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/Controls/TypeDropdown.js
15 ↗(On Diff #11226)

list assignments can happen in the constructor instead of every page open

Nescio removed a subscriber: Nescio.Feb 9 2020, 9:31 AM
elexis added a comment.Feb 9 2020, 1:58 PM
  • TODO: If currently selected map is not part of this list, remove the selected index
  • The missing scrolling is really bad. I didnt check your JS scrolling implementation, but a slider might also work as a workaround.
  • The code doesnt work as intended for clients (that aren't the host) unless I missed something reading the code

Changed it to look like this:

binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MapBrowserPage.xml
26

6px border is too much / bold /harsh, 3px

43

It's easier to not split "Page: " and "x/y", but to use the same GUI object.

89

size -4 leaves an unpermitted overlapping with the gridbrowser selection marker

nani added a comment.Feb 9 2020, 3:09 PM
  • The missing scrolling is really bad. I didnt check your JS scrolling implementation, but a slider might also work as a workaround.

What scrolling implementation?

  • The code doesnt work as intended for clients (that aren't the host) unless I missed something reading the code

As the map browser was previously a different page the only host vs client check was on the callback handle in game setup page. Now the check should be on the the map browser code itself.

elexis added a comment.Feb 9 2020, 3:27 PM
In D1703#110031, @nani wrote:
  • The missing scrolling is really bad. I didnt check your JS scrolling implementation, but a slider might also work as a workaround.

What scrolling implementation?

None.

  • The code doesnt work as intended for clients (that aren't the host) unless I missed something reading the code

As the map browser was previously a different page the only host vs client check was on the callback handle in game setup page. Now the check should be on the the map browser code itself.

Clients should be able to use the mapbrowser as well, so that they can propose a different map to the host.
In that case the Select button must be hidden and the cancel button right aligned.

  • Computing minColumns / maxColumns (zoom limits) depending on image aspect ratio and current available vertical and horizontal screenspace and minimum image width only
  • Disabling the Zoom buttons when the zoom limit was reached
  • Disabling/enabling the Select button if there is no selection (selection removal can happen if there are no text filter matches)
  • Deleted the png, too saturated colors, used a "Browse Maps" Modern themed button below the MapSelection dropdown and assigned the mappreview image click to open the mapbrowser too
  • Added the generic GameSettingControlButton class to achieve that.

There was an irc survey yesterday on the two proposed styles with a plural of opinions.
Considering that the mapbrowser appears better with the filters in the top line with 1024*768, that's what's being uploaded.

binaries/data/mods/public/gui/gamesetup/Pages/GameSetupPage/Panels/Buttons/MapBrowserButton.xml
13 ↗(On Diff #11226)
binaries/data/mods/public/gui/gamesetup/Pages/GameSetupPage/Panels/MapPreview.xml
6

The MapPreview class / image object can become clickable as well as a shortcut to select a map.
A tooltip is added to notify the user of this possible action.

6

Implementing the class GameSettingControlButton extends GameSettingControl and listing it below the map selection dropdown.

binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/Controls/SelectButton.js
18

select map with cancel = copypaste error

binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/Controls/ZoomInButton.js
18

"Make bigger", "Make smaller" better make that "Zoom", "Increase" / "Decrease".

binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MapBrowserPage.js
49

onMouseWheelDown only works for the grid browser items that are of type "image". Perhaps I made a mistake somewhere or is this dead code? I have to remove it until its implemented in a way that works. (I didn't quickly find a reason in source/gui/ why its hidden, perhaps because the children are ghosts or hidden or whatever)

49

The tooltip is a lie!
MouseWheel does not increase mapsize anywhere!
I suggest to add new hotkeys Ctrl+MouseWheelUp and Ctrl+MouseWheelDown. I mean someone could do that.

binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MapBrowserPage.xml
96

Close should be cancel, so that it becomes obvious that the selection will be discarded.

elexis updated this revision to Diff 11320.Feb 10 2020, 4:22 PM
elexis edited the summary of this revision. (Show Details)

elexis rewrite v1

Successful build - Chance fights ever on the side of the prudent.

Linter detected issues:
Executing section Source...
Executing section JS...
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 4 spaces.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|  17|  17|  */
|  18|  18| MatchSort.get = function(input, list, key)
|  19|  19| {
|  20|    |-    input = input.toLowerCase();
|    |  20|+	input = input.toLowerCase();
|  21|  21| 
|  22|  22|     let result = [];
|  23|  23| 
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 4 spaces.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|  19|  19| {
|  20|  20|     input = input.toLowerCase();
|  21|  21| 
|  22|    |-    let result = [];
|    |  22|+	let result = [];
|  23|  23| 
|  24|  24|     for (let obj of list)
|  25|  25|     {
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 4 spaces.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|  21|  21| 
|  22|  22|     let result = [];
|  23|  23| 
|  24|    |-    for (let obj of list)
|    |  24|+	for (let obj of list)
|  25|  25|     {
|  26|  26|         let text = key == null ? obj : obj[key];
|  27|  27|         let score = MatchSort.scoreText(input, text);
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 4 spaces.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|  22|  22|     let result = [];
|  23|  23| 
|  24|  24|     for (let obj of list)
|  25|    |-    {
|    |  25|+	{
|  26|  26|         let text = key == null ? obj : obj[key];
|  27|  27|         let score = MatchSort.scoreText(input, text);
|  28|  28|         if (score !== undefined)
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 8 spaces.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|  23|  23| 
|  24|  24|     for (let obj of list)
|  25|  25|     {
|  26|    |-        let text = key == null ? obj : obj[key];
|    |  26|+		let text = key == null ? obj : obj[key];
|  27|  27|         let score = MatchSort.scoreText(input, text);
|  28|  28|         if (score !== undefined)
|  29|  29|             result.push([obj, score, text, text.startsWith(input)])
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 8 spaces.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|  24|  24|     for (let obj of list)
|  25|  25|     {
|  26|  26|         let text = key == null ? obj : obj[key];
|  27|    |-        let score = MatchSort.scoreText(input, text);
|    |  27|+		let score = MatchSort.scoreText(input, text);
|  28|  28|         if (score !== undefined)
|  29|  29|             result.push([obj, score, text, text.startsWith(input)])
|  30|  30|     }
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 8 spaces.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|  25|  25|     {
|  26|  26|         let text = key == null ? obj : obj[key];
|  27|  27|         let score = MatchSort.scoreText(input, text);
|  28|    |-        if (score !== undefined)
|    |  28|+		if (score !== undefined)
|  29|  29|             result.push([obj, score, text, text.startsWith(input)])
|  30|  30|     }
|  31|  31| 
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 3 tabs but found 12 spaces.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|  26|  26|         let text = key == null ? obj : obj[key];
|  27|  27|         let score = MatchSort.scoreText(input, text);
|  28|  28|         if (score !== undefined)
|  29|    |-            result.push([obj, score, text, text.startsWith(input)])
|    |  29|+			result.push([obj, score, text, text.startsWith(input)])
|  30|  30|     }
|  31|  31| 
|  32|  32|     return result.sort(MatchSort.sort).map(v => v[0]);
|    | [NORMAL] ESLintBear (semi):
|    | Missing semicolon.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|  26|  26|         let text = key == null ? obj : obj[key];
|  27|  27|         let score = MatchSort.scoreText(input, text);
|  28|  28|         if (score !== undefined)
|  29|    |-            result.push([obj, score, text, text.startsWith(input)])
|    |  29|+            result.push([obj, score, text, text.startsWith(input)]);
|  30|  30|     }
|  31|  31| 
|  32|  32|     return result.sort(MatchSort.sort).map(v => v[0]);
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 4 spaces.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|  27|  27|         let score = MatchSort.scoreText(input, text);
|  28|  28|         if (score !== undefined)
|  29|  29|             result.push([obj, score, text, text.startsWith(input)])
|  30|    |-    }
|    |  30|+	}
|  31|  31| 
|  32|  32|     return result.sort(MatchSort.sort).map(v => v[0]);
|  33|  33| };
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 4 spaces.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|  29|  29|             result.push([obj, score, text, text.startsWith(input)])
|  30|  30|     }
|  31|  31| 
|  32|    |-    return result.sort(MatchSort.sort).map(v => v[0]);
|    |  32|+	return result.sort(MatchSort.sort).map(v => v[0]);
|  33|  33| };
|  34|  34| 
|  35|  35| MatchSort.sort = function([o1, s1, t1, a1], [o2, s2, t2, a2])
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 4 spaces.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|  34|  34| 
|  35|  35| MatchSort.sort = function([o1, s1, t1, a1], [o2, s2, t2, a2])
|  36|  36| {
|  37|    |-    if (a1 && a2)
|    |  37|+	if (a1 && a2)
|  38|  38|         return t1.localeCompare(t2);
|  39|  39| 
|  40|  40|     if (a1)
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 8 spaces.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|  35|  35| MatchSort.sort = function([o1, s1, t1, a1], [o2, s2, t2, a2])
|  36|  36| {
|  37|  37|     if (a1 && a2)
|  38|    |-        return t1.localeCompare(t2);
|    |  38|+		return t1.localeCompare(t2);
|  39|  39| 
|  40|  40|     if (a1)
|  41|  41|         return -1;
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 4 spaces.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|  37|  37|     if (a1 && a2)
|  38|  38|         return t1.localeCompare(t2);
|  39|  39| 
|  40|    |-    if (a1)
|    |  40|+	if (a1)
|  41|  41|         return -1;
|  42|  42| 
|  43|  43|     if (a2)
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 8 spaces.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|  38|  38|         return t1.localeCompare(t2);
|  39|  39| 
|  40|  40|     if (a1)
|  41|    |-        return -1;
|    |  41|+		return -1;
|  42|  42| 
|  43|  43|     if (a2)
|  44|  44|         return 1;
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 4 spaces.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|  40|  40|     if (a1)
|  41|  41|         return -1;
|  42|  42| 
|  43|    |-    if (a2)
|    |  43|+	if (a2)
|  44|  44|         return 1;
|  45|  45| 
|  46|  46|     return s1 - s2;
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 8 spaces.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|  41|  41|         return -1;
|  42|  42| 
|  43|  43|     if (a2)
|  44|    |-        return 1;
|    |  44|+		return 1;
|  45|  45| 
|  46|  46|     return s1 - s2;
|  47|  47| };
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 4 spaces.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|  43|  43|     if (a2)
|  44|  44|         return 1;
|  45|  45| 
|  46|    |-    return s1 - s2;
|    |  46|+	return s1 - s2;
|  47|  47| };
|  48|  48| 
|  49|  49| /**
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 4 spaces.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|  51|  51|  */
|  52|  52| MatchSort.scoreText = function(input, text)
|  53|  53| {
|  54|    |-    // Exact match
|    |  54|+	// Exact match
|  55|  55|     if (input == text)
|  56|  56|         return MatchSort.Highscore;
|  57|  57| 
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 4 spaces.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|  52|  52| MatchSort.scoreText = function(input, text)
|  53|  53| {
|  54|  54|     // Exact match
|  55|    |-    if (input == text)
|    |  55|+	if (input == text)
|  56|  56|         return MatchSort.Highscore;
|  57|  57| 
|  58|  58|     text = text.toLowerCase();
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 8 spaces.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|  53|  53| {
|  54|  54|     // Exact match
|  55|  55|     if (input == text)
|  56|    |-        return MatchSort.Highscore;
|    |  56|+		return MatchSort.Highscore;
|  57|  57| 
|  58|  58|     text = text.toLowerCase();
|  59|  59| 
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 4 spaces.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|  55|  55|     if (input == text)
|  56|  56|         return MatchSort.Highscore;
|  57|  57| 
|  58|    |-    text = text.toLowerCase();
|    |  58|+	text = text.toLowerCase();
|  59|  59| 
|  60|  60|     // Exact match relaxed
|  61|  61|     if (input == text)
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 4 spaces.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|  57|  57| 
|  58|  58|     text = text.toLowerCase();
|  59|  59| 
|  60|    |-    // Exact match relaxed
|    |  60|+	// Exact match relaxed
|  61|  61|     if (input == text)
|  62|  62|         return MatchSort.Highscore / 2;
|  63|  63| 
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 4 spaces.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|  58|  58|     text = text.toLowerCase();
|  59|  59| 
|  60|  60|     // Exact match relaxed
|  61|    |-    if (input == text)
|    |  61|+	if (input == text)
|  62|  62|         return MatchSort.Highscore / 2;
|  63|  63| 
|  64|  64|     let score = 0;
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 8 spaces.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|  59|  59| 
|  60|  60|     // Exact match relaxed
|  61|  61|     if (input == text)
|  62|    |-        return MatchSort.Highscore / 2;
|    |  62|+		return MatchSort.Highscore / 2;
|  63|  63| 
|  64|  64|     let score = 0;
|  65|  65|     let offset = -1;
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 4 spaces.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|  61|  61|     if (input == text)
|  62|  62|         return MatchSort.Highscore / 2;
|  63|  63| 
|  64|    |-    let score = 0;
|    |  64|+	let score = 0;
|  65|  65|     let offset = -1;
|  66|  66| 
|  67|  67|     for (let i = 0; i < input.length; ++i)
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 4 spaces.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|  62|  62|         return MatchSort.Highscore / 2;
|  63|  63| 
|  64|  64|     let score = 0;
|  65|    |-    let offset = -1;
|    |  65|+	let offset = -1;
|  66|  66| 
|  67|  67|     for (let i = 0; i < input.length; ++i)
|  68|  68|     {
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 4 spaces.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|  64|  64|     let score = 0;
|  65|  65|     let offset = -1;
|  66|  66| 
|  67|    |-    for (let i = 0; i < input.length; ++i)
|    |  67|+	for (let i = 0; i < input.length; ++i)
|  68|  68|     {
|  69|  69|         let offsetNext = text.indexOf(input[i], offset + 1);
|  70|  70| 
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 4 spaces.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|  65|  65|     let offset = -1;
|  66|  66| 
|  67|  67|     for (let i = 0; i < input.length; ++i)
|  68|    |-    {
|    |  68|+	{
|  69|  69|         let offsetNext = text.indexOf(input[i], offset + 1);
|  70|  70| 
|  71|  71|         // No match
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 8 spaces.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|  66|  66| 
|  67|  67|     for (let i = 0; i < input.length; ++i)
|  68|  68|     {
|  69|    |-        let offsetNext = text.indexOf(input[i], offset + 1);
|    |  69|+		let offsetNext = text.indexOf(input[i], offset + 1);
|  70|  70| 
|  71|  71|         // No match
|  72|  72|         if (offsetNext == -1)
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 8 spaces.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|  68|  68|     {
|  69|  69|         let offsetNext = text.indexOf(input[i], offset + 1);
|  70|  70| 
|  71|    |-        // No match
|    |  71|+		// No match
|  72|  72|         if (offsetNext == -1)
|  73|  73|             return undefined;
|  74|  74| 
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 8 spaces.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|  69|  69|         let offsetNext = text.indexOf(input[i], offset + 1);
|  70|  70| 
|  71|  71|         // No match
|  72|    |-        if (offsetNext == -1)
|    |  72|+		if (offsetNext == -1)
|  73|  73|             return undefined;
|  74|  74| 
|  75|  75|         // Lower score increase if consecutive index
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 3 tabs but found 12 spaces.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|  70|  70| 
|  71|  71|         // No match
|  72|  72|         if (offsetNext == -1)
|  73|    |-            return undefined;
|    |  73|+			return undefined;
|  74|  74| 
|  75|  75|         // Lower score increase if consecutive index
|  76|  76|         let isConsecutive = offsetNext == offset + 1 ? 0 : 1;
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 8 spaces.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|  72|  72|         if (offsetNext == -1)
|  73|  73|             return undefined;
|  74|  74| 
|  75|    |-        // Lower score increase if consecutive index
|    |  75|+		// Lower score increase if consecutive index
|  76|  76|         let isConsecutive = offsetNext == offset + 1 ? 0 : 1;
|  77|  77|         score += offsetNext + isConsecutive * offsetNext;
|  78|  78|         offset = offsetNext;
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 8 spaces.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|  73|  73|             return undefined;
|  74|  74| 
|  75|  75|         // Lower score increase if consecutive index
|  76|    |-        let isConsecutive = offsetNext == offset + 1 ? 0 : 1;
|    |  76|+		let isConsecutive = offsetNext == offset + 1 ? 0 : 1;
|  77|  77|         score += offsetNext + isConsecutive * offsetNext;
|  78|  78|         offset = offsetNext;
|  79|  79|     }
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 8 spaces.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|  74|  74| 
|  75|  75|         // Lower score increase if consecutive index
|  76|  76|         let isConsecutive = offsetNext == offset + 1 ? 0 : 1;
|  77|    |-        score += offsetNext + isConsecutive * offsetNext;
|    |  77|+		score += offsetNext + isConsecutive * offsetNext;
|  78|  78|         offset = offsetNext;
|  79|  79|     }
|  80|  80| 
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 8 spaces.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|  75|  75|         // Lower score increase if consecutive index
|  76|  76|         let isConsecutive = offsetNext == offset + 1 ? 0 : 1;
|  77|  77|         score += offsetNext + isConsecutive * offsetNext;
|  78|    |-        offset = offsetNext;
|    |  78|+		offset = offsetNext;
|  79|  79|     }
|  80|  80| 
|  81|  81|     return score;
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 4 spaces.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|  76|  76|         let isConsecutive = offsetNext == offset + 1 ? 0 : 1;
|  77|  77|         score += offsetNext + isConsecutive * offsetNext;
|  78|  78|         offset = offsetNext;
|  79|    |-    }
|    |  79|+	}
|  80|  80| 
|  81|  81|     return score;
|  82|  82| };
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 4 spaces.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|  78|  78|         offset = offsetNext;
|  79|  79|     }
|  80|  80| 
|  81|    |-    return score;
|    |  81|+	return score;
|  82|  82| };
|  83|  83| 
|  84|  84| MatchSort.Highscore = -10E7;

binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/MatchSort.js
|  29| ············result.push([obj,·score,·text,·text.startsWith(input)])
|    | [NORMAL] JSHintBear:
|    | Missing semicolon.
|    | [NORMAL] ESLintBear (semi):
|    | Missing semicolon.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/GridBrowserItem.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/GridBrowserItem.js
|   8|   8| 
|   9|   9| 		imageObject.onMouseLeftPress = this.select.bind(this);
|  10|  10| 		imageObject.onMouseWheelUp = gridBrowser.nextPage.bind(gridBrowser);
|  11|    |-		imageObject.onMouseWheelDown = gridBrowser.previousPage.bind(gridBrowser)
|    |  11|+		imageObject.onMouseWheelDown = gridBrowser.previousPage.bind(gridBrowser);
|  12|  12| 
|  13|  13| 		gridBrowser.registerGridResizeHandler(this.onGridResize.bind(this));
|  14|  14| 		gridBrowser.registerPageChangeHandler(this.updateVisibility.bind(this));

binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/GridBrowserItem.js
|  11| »   »   imageObject.onMouseWheelDown·=·gridBrowser.previousPage.bind(gridBrowser)
|    | [NORMAL] JSHintBear:
|    | Missing semicolon.
|    | [NORMAL] ESLintBear (semi):
|    | Missing semicolon.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/Controls/PageCounter.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/Controls/PageCounter.js
|  24|  24| };
|  25|  25| 
|  26|  26| MapBrowserPageControls.PageCounter.prototype.ItemCountCaption =
|  27|    |-	translate("Maps: %(mapCount)s")
|    |  27|+	translate("Maps: %(mapCount)s");
|  28|  28| 
|  29|  29| MapBrowserPageControls.PageCounter.prototype.PageCaption =
|  30|  30| 	translate("Page: %(currentPage)s/%(maxPage)s");

binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/Controls/PageCounter.js
|  27| »   translate("Maps:·%(mapCount)s")
|    | [NORMAL] JSHintBear:
|    | Missing semicolon.
|    | [NORMAL] ESLintBear (semi):
|    | Missing semicolon.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/Controls/MapBrowserFilter.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/Controls/MapBrowserFilter.js
|   5|   5| 		let labelWidth = Engine.GetTextWidth(this.label.font, this.label.caption) + 15;
|   6|   6| 
|   7|   7| 		{
|   8|    |-			let size = this.label.size
|    |   8|+			let size = this.label.size;
|   9|   9| 			size.right = labelWidth;
|  10|  10| 			this.label.size = size;
|  11|  11| 		}

binaries/data/mods/public/gui/gamesetup/Pages/MapBrowserPage/Controls/MapBrowserFilter.js
|   8| »   »   »   let·size·=·this.label.size
|    | [NORMAL] JSHintBear:
|    | Missing semicolon.
Executing section cli...

Link to build: https://jenkins.wildfiregames.com/job/docker-differential/1745/display/redirect

There are scrollbars in the Language and Mod Selection, perhaps those can be reused here?

elexis added a subscriber: Nescio.Feb 10 2020, 6:12 PM

There are scrollbars in the Language and Mod Selection, perhaps those can be reused here?

Scrollbars are in the current codebase only supported for "text" and "dropdown", "list", and "olist" (tables), but not for GUI objects that are parent to multiple GUI objects.

Scrollbars are in the current codebase only supported for "text" and "dropdown", "list", and "olist" (tables), but not for GUI objects that are parent to multiple GUI objects.

That sounds complicated.

nani commandeered this revision.Feb 12 2020, 10:47 PM
nani edited reviewers, added: elexis; removed: nani.
nani updated this revision to Diff 11331.Feb 12 2020, 10:53 PM

Improved the interface controls and made them fit them all on the right panel.
Made the search box expand the search to all maps if doesn't find of the current type and filter.
Added missing tooltips for the buttons.

nani edited the summary of this revision. (Show Details)Feb 12 2020, 10:58 PM
Nescio removed a subscriber: Nescio.Feb 13 2020, 9:44 AM