Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(FR) Add setting for default window size, position #44

Open
slgoldberg opened this issue Jul 16, 2019 · 11 comments
Open

(FR) Add setting for default window size, position #44

slgoldberg opened this issue Jul 16, 2019 · 11 comments
Assignees

Comments

@slgoldberg
Copy link

(Feature request): Add a setting for default window size and position.

This would be really useful for me when I'm using a smaller monitor, or my laptop without a separate screen, to run X-Plane.

In that scenario (i.e., lower total boxel area for screen), the default size and position of new windows is pretty terrible in DRT today. Until I make it smaller myself, each new window starts out by eclipsing a largeish area, somewhere near the middle of the screen. This is not only because it's in a bad place to start, but it's also much bigger than it needs to be to start (for some use-cases, anyway).

I know there are multiple use-cases here -- but when I'm just trying to get something done -- for example, changing a single dataref value -- I don't need a big area for search results. Of course I know I can save that one dataref as a window of my favorite size and position today -- but I also hate having to manage 20 windows each time I resize the monitor, for example.

So, I'd just love to be able to save a template (as it were) for my preferred window style, or a preference just to say "start with big" or "start with small", etc., and have that be where all windows (until I change it again later) would start and be sized as.

But -- all that potential complexity is simplified away with my pretty simple proposal/request:

Recommended feature: (much simpler than the lead-in, above!)

  • Always open each new window at the last coordinates (position and size) of the previously closed window. (AKA, "sticky ghosting", i.e., "previously-resized/-repositioned window is prototype for next new window".)

Implementation idea: (and way to scale into more useful feature over time)

  • Whether you make it a user-visible setting anywhere or not (even if you don't do sticky ghosting, developers who know JSON can still manually edit the .json file to set it if you don't have a UI yet), simply add another window object (or named preference that looks basically like a window in JSON) to the .json file. If it's a separate setting, it'd be called "default_window", for example as just another setting:
    ... "default_window": { "window_height": "78", "window_width": "359", "x": "1886", "y": "-76" }, ...

  • Alternatively, and I think simpler but also more powerful, you can simply use a sentinel search_team value to indicate this is the proxy descriptor for all new windows created.

In other words, instead of adding another preference, just add another ghost window to the list of existing windows. And give it a special name (or blank), such as "default_window" (not a good one, but you get the point), e.g.:

"windows": [ { "search_term": "**_default_window_**", "window_height": "78", "window_width": "359", "x": "1886", "y": "-76" }, { "search_term": "sim/foo/bar", "window_height": "123", "window_width": "482", ... } ], ...
or specially-named window, in the normal "windows" list. When the window has the special name (or none), then you use that as the template for new windows. In that case, however, it may be more complex in terms of what to do with the options, e.g.:

"case_sensitive": "false", "regex": "true", "changed": "false", "big_changes_only": "false", "search_term": ""

One the one hand, you could save them, too -- so, they're always cloned from the last window you close, or something. Or on the other hand, you could just ignore them and use the real settings as expected. Or -- better yet -- to simplify (my recommendation) the user experience and documentation, you simply leave them out or make it a separate section as above.

I am hoping you can slide this one little baby feature request in for the next wave of changes you're making right now, if possible. :-)

Thanks!

Steve

@leecbaker
Copy link
Owner

Hi Steve,

Lots to think about here. I have very limited time to spend on DRT, but I would love to improve the window management situation.

You've described lots of great ideas here- let me think about it for a few days and I'll see what I can do.

-Lee

@slgoldberg
Copy link
Author

Sounds good, thanks for the response.

I really wanted to just send you a pull request :-) but I'm in the middle of getting my own next release out for ABC, in collaboration with TwinFan on LiveTraffic.. (it's looking great, but I'm not quite at a point to take on another project).

I do also think if you think about it, it'll be relatively straightforward vs. if I try to do it it will probably be something you'll just laugh at. :-)

Thanks. And feel free to bounce anything off me as you think through it .. maybe alternatives will come to mind. If it's too much work, too, I understand if you need to put it on the back-burner.

Steve

@leecbaker
Copy link
Owner

Hi Steve,

One possible (and more complicated) solution here is have window position presets. Add menu options to save or restore the current windows to/from a numbered save slot. I think this will ultimately be the direction I'll go. The save slots can represent user-created profiles, have commands for restoring that set of windows, etc. And of course, there will now have to be a user preference for which save slot to load by default. And a magic save slot that's simply the position of the windows the last time X-Plane was closed.

In the meantime, I'm trying to find a clean solution for resizing and repositioning windows that are positioned at the edge of the screen. Sounds easy, but there are a million little details that complicate this, including window resizing, the auto hiding menu bar, switching in and out of fullscreen mode / VR, popping out windows, etc. Plus the complication that sometimes, when loading, X-Plane will report the screen resolution as 1024x768 or some constant, rather than the actual window / screen size.

One other enhancement that's also related to windows: I'd love to be able to dock a DRT window to the edge of the screen - this way when the screen changes, the DRT window stays on whatever edge of the screen it was docked to. This might solve some of the resizing issues.

Anyway, those are my thoughts so far. I'm also trying to get a release of PlaneCommand (beta) out the door in the next week or so- got lots of major changes in the works!

Hey do you have an email address where I can contact you about Live Traffic? Can you send me an email (lee@planecommand.com or lee@leecbaker.com)?

-Lee

@slgoldberg
Copy link
Author

Well, I do think that would be an interesting feature to look at .. though it sounds like it would not address the use-case I'm setting forth in my feature request.

If I understand your idea -- whereas, today, there is only one "set" or profile of saved windows (i.e., the current set of windows that get restored each session), you'd allow the user to have multiple such sets -- and furthermore, to number/name them into slots that the user can choose from the menu. (Is this roughly it?)

I could see that being a useful feature, especially (probably for me -- ONLY) if it has a commandref defined for each slot (so I can bind a keyboard shortcut or joystick button to cause each saved set to appear/disappear as a toggle per set). That would be awesome. (Note that, if I could only restore a set using a menu and not a commandref, and I couldn't close all the windows at once somehow with a commandref as well, then I'm pretty likely never to use that feature.)

But, I think either way, this proposal doesn't actually solve my use-case above. In other words, there's nothing different in the persisted multi-set world that I can't already do in today's persisted single-set world, i.e., I could I suppose achieve my need by simply reusing the same saved window each time. But I'm proposing to create new windows in a different location, and of a different size, .. irrespective of any saved windows I have. I don't want to mix the two modalities:

  • persistent windows = regular datarefs I want to monitor or modify on a regular basis
  • creating a new windows = (in my case) ad-hoc queries that are goal-oriented (unpredictable)

So, I don't want the query to be saved for my new-window idea -- just the position and size. Whereas your suggestion still requires me to reuse an old window, thus replacing the saved query of that window, whether it's in a set A, B, or C. Am I making sense?

Also, I wonder whether profiles are really needed .. Certainly for the persistent windows case above, it might be a better experience to just open/close the set of windows when I need them, rather than have to manually manage them being just at the very bottom, barely visible, each time things change...

But again -- even for that to be useful -- I'd really want to be able to use a commandref to open/close the set of saved windows (even if to start it's just "all currently-persisted windows/queries". Moreover, I'd want to be able to close them equally simply using a commandref.

[In fact, this makes me think of the bug someone filed a while ago, saying he was getting lots of windows on top of themselves. He was probably repeating the "new-window" commandref you have, and not understanding that he needed to just do a one-time command not a continuous command or something. But if one does do that, it's really annoying to have to close each window manually using the close-box. It would be nice if just like a commandref to open a new window, there was a commandref to close the topmost window (i.e., last opened window). But this is a different topic.]

-- Changing gears to the second part of your last message:

Re: the question of docking windows in a more semantic way, I like that idea and don't think it would be too hard -- unless you don't want to risk user confusion in those edge cases where XPLM screws you. (The biggest bug that I've found being that if the user changes the UI to 150% or 200%, XPLM fails to pass the new window boundaries on, and keeps giving the same previous boundaries.. until you restart X-Plane).

But since you already do a good job of making sure the user never "loses" windows, i.e., that they're always visible, it seems like you have the seeds of this already. I do something in ABC where I basically constantly query the window boundaries on each draw callback (and in other places) and assuming XPLM doesn't leave you high and dry, it's not that hard (and I think you already do it) to just audit the window location and act accordingly.

For both "docked" windows, and in fact any windows that are off-screen, I think the algorithm I came up with below is on the right track .. though I'm not sure it's right as I ended up hacking up something not as elegant due to as you said lots of complexity. :-) But I think it would actually work... read on.

For undocked windows, we just have to define a minimum number of boxels the window must have visible so users can drag the window, etc., otherwise it will need to be repositioned automatically. But for docked windows, I think that value is simply 0. I.e., if min_onscreen_boxels that I define below can be per-window, then we have something.. you'd of course need more state than this example, but you can work that out I'm sure. :-)

But let's say for pseudocode's sake that we are just handling floating windows, but I think you can extend it to docked pretty simply.. By saying we have the following: window_left, window_right, window_top, window_bottom, min_onscreen_boxels, window_height, window_width*. With these, I think there are just four cases to consider -- but because you want to handle both axes you probably need to make this an 8-way thing, but .. let's simplify for now and just say there are 4 cases:

(*Note: in reality, the top onscreen boxels number needs to account for the menu bar, too, so it's not the same on all four sides. Also, what makes the pseudocode below seem asymmetric is that the y-axis is inverted from the x-axis, unfortunately, thanks to XPLM's I guess somewhat sensible axes for the 2D interface.) Caveat emptor: as I'm getting tired as I write this, so I likely have bugs below, but hopefully you get the gist:

  • case 1: if (window_right < gScreen_left + min_onscreen_boxels) => window is off left screen, reposition horizontally (without changing the window width):

    • window_left = gScreen_left
    • window_right = window_left + window_width
  • case 2: if (window_top < gScreen_bottom + min_onscreen_boxels) => window is off bottom of screen, reposition vertically (without changing the window height):

    • window_bottom = gScreen_bottom
    • window_top = window_bottom + window_height

... the rest as an exercise to the reader, I'm losing steam here ... :-)

As long as you call XPLMGetScreenBoundsGlobal() before you check these (and update the globals mentioned, e.g. gScreen_{top,bottom,left,right} each cycle, then you can audit (i.e., the comparisons and assignments in pseudocode above) and I think it just works. :-)

In most cases. :-)

-- And finally:

As for email, I'm happy to talk about other stuff off this thread, no problem. Feel free to email me at brat at footbag dot org. If that's not clear, let me know (just slightly worried about spam bots scraping addresses.)

For LiveTraffic, TwinFan is the guy to talk to .. I think his address is in the documentation linked off the download page on the dot-org site, as well as in his GitHub (for which his username is simply TwinFan).

Let me know if that was what you were asking. Thanks again!

Steve

@leecbaker leecbaker self-assigned this Jul 22, 2019
@leecbaker
Copy link
Owner

Steve,

Thanks for all the ideas here. This discussion has me thinking about more and more window-related ideas. I think I'm going to try to do one release of DRT soon, and then work on window management-related features for the next release.

-Lee

@leecbaker
Copy link
Owner

@slgoldberg Rather than setting a default window size in the preferences file, is there a programmatic default that would make sense? I think right now, windows are simply 500x400 boxels, in the center of the screen. Perhaps we can scale this by screen size?

Another idea I just had- what if there was a command to toggle whether all DRT windows were hidden? Would that help on small screens? I guess you can emulate this by enabling / disabling the DRT plugin.

@slgoldberg
Copy link
Author

slgoldberg commented Jul 24, 2019

tl/dr:
Default size: 400 x 140 boxels
Default position: just inset (10-20 boxels max) from bottom left, center, or right edge

User can easily reposition as needed from there.

Also, add a command to close the last-opened window, and auto-focus on the input field after new-window creation, if possible.

--- More detailed response, and rationale:

Well, I think the issue is that there are three primary use-cases for DRT. Note, in my examples below, I bind ctrl-n to create a new window in DRT:

(1) Monitoring one or more datarefs that match a query (e.g. monitoring related things matching a pattern, and possibly looking only at changes, etc).

  • For this case, the default window size/location doesn't matter at all. Because the user will likely save this window and just keep it open off the side so they can drag it out to look at it. (Over the long term, the default new-window location is irrelevant to this use case.)
  • This was to my mind the original primary use-case for DRT. However, since DRT windows already can be saved quite nicely and restore automatically, this does not mean the new-window needs to be tailored to this use-case! In fact, it's because you can save a window of this nature how you like, that new-windows should not be tailored to this use-case at all.

(2) Viewing and likely changing a single (or maybe two related) dataref(s), and/or commandrefs, e.g. to change a specific mode quickly, immediately, and probably not again any time soon. (This happens a lot while debugging a new plug-in feature, for example, or trying various dataref-based changes that aren't in the UI, e.g. for scripting, etc., etc.). Experienced users who aren't even developers may well be falling into this use-case very often.

  • For this case, the default window size/location being tuned to this use would be very nice:
    • Recommendation: width=400 boxels, height=140-160 boxels.
  • Also, there is very little value to users to saving these windows between runs. They are one-time queries basically.
  • With a small window, (only showing a max of 2-3 result lines), the user can quickly type the query, see the result (if they've given a good enough unique query), and likely change the value of the dataref they are looking for.
  • Additionally, it would be nice (but doesn't work today) to have the cursor automatically start focused in the input field of the new window, so the user can just type the query right away after hitting (in my case, ctrl-n).
  • As indicated, the user would very likely then close the window, not keep it open, since it would be too much hassle to manage this type of window since it's usually just for a quick check or action.

(3) Searching for datarefs or commandrefs to try to discover the ones you want, and/or to see what's changing, also as a relatively one-time action.

  • For this case, you may want the window bigger, and you may want to be clicking the various modes (such as "only data" vs. "only commands" vs. "both" vs. "recently changed" etc.).
  • For this type of situation, the user is willing to be patient, i.e. to sit and click and tool around in their new window.
  • So, opening the window at the width recommended in use-case 2 above is not a big problem for people in this category. They can just resize the window if they want to see lots of related results.

What do you think? 400 wide by 160 tall? I would love it.

Finally -- in terms of where to open this window:

(1) The middle of the screen couldn't be a worse place to open a new window using a command such as a key binding.

(2) I recommend instead putting the window on the bottom (either near the bottom left or bottom right edge, or else I guess it's fine if it's in the bottom center, too -- but that's my third choice).

(3) Therefore, as relative boxel positions, the algorithm for bottom-left would be something like: width = 400; height = 160; bottom = 20; top = bottom + height; left = 20; right = left + width;

Of course, you offset the whole thing by the real screen position. But that only applies to the two assignments left = and bottom = -- everything else is calculated relative to width and height.

Make sense?

tl/dr:
Default size: 400 x 140 boxels
Default position: just inset (10-20 boxels max) from bottom left, center, or right edge

User can easily reposition as needed from there.

Also, add a command to close the last-opened window.

Thanks! :-)

Steve

P.S. Sorry -- had to edit to just clarify and move the tl/dr. But I also had one last thought: it would also be really nice if you could add a little padding for the drag/resize zone for these windows. Maybe just 4 more boxels total on each edge, i.e., 2 more for drag grab zone, and 2 more for resize grab zone.

(If you can't do that, I understand. Windows are annoying using the various XPLM modes, it's kind of all or nothing. I build all my own windows and/or widgets, including scroll bar from scratch, in ABC because of this.)

@slgoldberg
Copy link
Author

Whoops, completely missed your second question:

Another idea I just had- what if there was a command to toggle whether all DRT windows were hidden? Would that help on small screens? I guess you can emulate this by enabling / disabling the DRT plugin.

Yes, that's a great idea. I would love it -- especially if it meant I could hide all DRT windows before resizing the display to experiment around. I.e., if I resize the display back before unhiding DRT windows, then they in theory wouldn't move.

Which makes me realize: it would be even better if all restored windows start out hidden, and you basically unhide-all by using this single simple command to toggle DRT on/off. Default to off, but users can have a setting to say they want to have it start on.

Make sense? I love it. Simple commandref, toggle DRT on/off, and menu to correspond to it. But must must must have commandref. Hate menus. :-)

Also -- for people with complex watchlists in DRT, they can actually ensure DRT isn't itself slowing down the simulator just updating constantly (especially if the windows are still "on-screen" but clipped off the edge, etc.). It would just be really nice I think.

So I recommend having a single commandref to hide/show windows (toggle DRT on/off) and if a user hits the DRT "new window" command, it will auto-unhide all windows because it's implicit.

Make sense?

Ohhhh, and that reminds me: shouldn't your own datarefs and commandrefs be listed in your .../Output/preferences/drt_last_run_{command,data}refs.txt files? Because for example I went to search for the commandref for open-window earlier, and it's not listed in that file. Would be nice if it was. :-)

Thanks.

Steve

@slgoldberg
Copy link
Author

Or instead of making a new setting to say whether you want DRT window on vs. off at start, how about just making the current state sticky.. I.e., whatever mode the user was last in when they quit X-Plane, they can rely on that state persisting when they return. So, if they had flipped DRT to "off" mode and restarted X-Plane, then DRT would still be in "off" mode 'til they either open a new window or explicitly toggle DRT back on. (Both would turn DRT back on.)

Good idea!

Steve

@leecbaker
Copy link
Owner

That's a great breakdown of the ways that people use DRT. Personally, virtually all of what I do is in category 3.

But must must must have commandref. Hate menus. :-)
I'm of the opinion now that everything that can be a command, should be a command. In particular, menus items should always be commands, and there should be datarefs to reflect status of menu items that are checked / unchecked. So we're on the same page here.

For category 2 usage of DRT, I wonder if there are other UIs that would fit this use case better than a window. If only monitoring one dataref, perhaps just overlaying the value of that dataref on the screen somewhere would make sense.

Another thought I had- we could make little tabs at the bottom of the screen that when clicked, slide up as a DRT window. Kind of like little drawers. They would take minimal space on the screen when not in use, and only require one click to slide up into the open position when needed.

Before I get to the point of doing experimentation with new UIs, I would at least like to use XPLM3 windows so they can be popped out for people with multiple monitors. That's the next big change to make.

for people with complex watchlists in DRT, they can actually ensure DRT isn't itself slowing down the simulator just updating constantly

There are two things in DRT that can slow down the simulator:

  • Reading a slow dataref. Since plugins can perform any arbitrary computations in the dataref provider functions, occasionally I see cases where this is slow; however, in general, this isn't a problem. (When I see it, I file a bug report). This is kind of amazing to me, since DRT reads 6000+ datarefs every flight loop.
  • Queries that use really complicated regular expressions who search datarefs that are changing. This is a rare case. Text searches are fast. Searching DR/CR names only happens once per search... unless you are searching for changing datarefs, of which there are usually less than 300.

In my experience, when compiled in release mode, DRT almost never slows down the simulator. This is easily verified by disabling the plugin. I worked really hard to make it this way.

Lots to digest here in your messages- I'll keep thinking about how to go about it in the future.

@slgoldberg
Copy link
Author

First of all, I never meant to imply that DRT might slow down the simulator. It absolutely doesn't. It's insanely fast. I was just saying it's a comforting thing for some users to think they don't have to worry about it if they're not in developing mode actively, but still have a bunch of saved windows hanging off the edges. They won't slow things down, but users might be happier to think they are "gone" while they have DRT toggled to "off" mode.

Glad we think the same way about commands. Agreed obviously 100%. :-)

Now, I think we still disagree (or maybe you don't still quite understand my meaning for use case 2 above). Basically, the problem is exactly that I do not want to have to re-use the same window (even if it's a nice easy-to-use tab) each time I want to do something in category 2. It's exactly the antithesis of what I want in such a situation! ...

In other words, category 2 is the situation in which I literally just want to:

  1. open a window
  2. type a query (hopefully without having to first resize the window and move it out of the way, then click inside the box to start typing)
  3. see the result
  4. optionally, change the value
  5. immediately and forever more close the window.

So, having to keep worrying whether a window is being used for something else, and not wanting to overwrite some other query I don't want to forget, I'll end up using up all the slots and that will suck. :-)

OK anyway, more later. Thanks.

Steve

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants