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

[suggestion/implementing] Make term library draw in user defined areas +a fix #1527

Closed
mpmxyz opened this issue Nov 16, 2015 · 12 comments
Milestone

Comments

@mpmxyz
Copy link
Contributor

mpmxyz commented Nov 16, 2015

I'm currently prototyping a term library modification that adds the possibility to limit all term drawing operations to a user defined area. That can be useful if you want to have a split screen with the shell and other command line programs on the bottom and something like a "reactor state monitor" on top.
The API would only get 2 additional methods:

  • term.setWindow(x, y, width, height)
  • term.getWindow() -> x, y, width, height

All values can be negative to indicate a side being relative to the lower right part of the screen.

  • y = -1 -> drawing area begins at the bottom line
  • width = -2 -> drawing area ends one column before the end of the screen

The prototype works but is ugly and I'd like to do a partial rewrite of term.
So my question is: Would you accept a pull request for such a modification?
Since I'd have to rewrite some parts of the library anyway, I'd also take the freedom to change some other things:

  • replace the combined gpu.copy/gpu.set calls in term.read by a single gpu.set call that redraws the whole line (Unless I understood something wrong gpu.set uses less of the 'gpu budget' than gpu.copy; this change also makes reimplementing the library easier.)
  • fix some errors with fullwidth characters (e.g. term.read does not highlight properly)
@fnuecke
Copy link
Member

fnuecke commented Nov 16, 2015

Sounds great! This is actually something I had hoped to do one day, but eventually never got around to. Would definitely accept a good PR for this.

Fixes: absolutely, please do. I'm not sure which part you mean with the copy/set, but even if I did I probably couldn't remember if there was any deeper meaning to it, so whatever works. And yeah, proper widechar support would be amazing.

Side thought: how does term.getWindow() know what to return? I.e. how does it know the running program? I imagine using process.info().data, like io does for program specific standard streams?

@mpmxyz
Copy link
Contributor Author

mpmxyz commented Nov 16, 2015

Originally I didn't even think about multiple windows, but that sounds nice, too.
The "one window only" version is almost finished and just needs to be tested and cleaned up a bit.
Current Progress: https://github.com/mpmxyz/OpenComputers/blob/patch-2/src/main/resources/assets/opencomputers/loot/OpenOS/lib/term.lua
The next step would be to implement an instancing system like you described. How would the API look like?
I imagine something like that:

  • term.newWindow(x, y, width, height) -> window object with methods like window:read(...)
  • term.setWindow() / term.bind / however the name to set the window used by the "old" API

And if I'm are already adding stuff like that I'd add the neat feature to specify a gpu for drawing.

@fnuecke
Copy link
Member

fnuecke commented Nov 17, 2015

Ah, having a single area and just specifying the area for that would be a lot easier than what I had thought of, and seems a lot more reasonable short term; unless you want to give it a shot, which'd be great!

As for an API... I'd actually not considered multiple windows per program (just one per, with its properties being stored in the process data). But something along those lines sounds good for full flexibility, yes. With the default window then being stored in the process data or so, inheriting its properties from the creating process (well, "process").

I think term.bind might be a little to inviting for confusion with gpu.bind, so term.setWindow sounds good to me.

And sure, once there's a 'window' object, having a 'setGpu' on it sounds comparatively trivial and would be quite helpful I imagine.

@mpmxyz
Copy link
Contributor Author

mpmxyz commented Nov 17, 2015

Current status: Testing & Bug Fixing
https://raw.githubusercontent.com/mpmxyz/ocprograms/master/pics/multiwindow.png
All functions work on multiple screens. (even term.read)
Current API:
term.setWindow(newWindow) -> oldWindow
term.getWindow() -> currentWindow
term.newWindow(x, y, width, height, gpu) -> window
term.setArea(x, y, width, height) -> oldX, oldY, oldW, oldH
term.getArea() -> x, y, width, height
term.setGPU(newGPU) -> oldGPU --use newGPU == nil to use the primary one at any time (even if it changes)
term.getGPU() -> (gpu), (gpu or component.gpu)
term.getAbsoluteArea() -> x, y, width, height --returns the calculated position and dimension of the drawing surface (needs a better name; good if you want your custom drawing to stay within term area)

@fnuecke
Copy link
Member

fnuecke commented Nov 17, 2015

Sounds great. For getAbsoluteArea, maybe getGlobalArea, or toGlobal(x, y, width, height)? (actually, probably just toGlobal(x,y), there's no scaling, is there? So getArea + toGlobal would cover that. And then also an accompanying toLocal, e.g. to translate mouse input to relative window coordinates.)

@mpmxyz
Copy link
Contributor Author

mpmxyz commented Nov 17, 2015

There is no scaling but the width and height in setArea/getArea can be negative to indicate that the lower/right border has a fixed distance to the lower/right end of the screen. You might need that information when you are drawing something.
Just another name to throw in: getTargetArea
toLocal(x, y) and toGlobal(x, y) are nice/simple enough that I just added them.

@fnuecke
Copy link
Member

fnuecke commented Nov 18, 2015

Ah, right, forgot about you mentioning the negative values. So those would be kept to dynamically adjust it on a resolution change I guess?

I kind of lean towards getGlobalArea, as its in sync with toGlobal, but I've no strong opinion on that one, tbh :P

@makkarpov
Copy link
Contributor

May window system have multiple cursors or cursor is displayed only in current window?

@fnuecke
Copy link
Member

fnuecke commented Nov 18, 2015

As in have a window.setKeyboard, too? Still would have to be a mix, in case two windows use the same keyboard (then one needs focus, IMHO).

@mpmxyz
Copy link
Contributor Author

mpmxyz commented Nov 18, 2015

Each window has its own cursor. But there is no possibility to have multiple inputs at once since you can't run term.read in parallel.
In CC there is the parallel API: It catches all events and forwards them to several coroutines.
What would you do in OC? All coroutine.yield and coroutine.resume are wrapped to allow signals passing through them.

There also isn't the concept of a "focus" or "current window". The only filter for keyboards is that only the first keyboard( of the screen( bound to the GPU( used by the window running term.read))) is listened to. (It's only the first keyboard because you get one event per keyboard.)

@fnuecke
Copy link
Member

fnuecke commented Nov 20, 2015

Yeah, the term lib is a bit broken wrt. to the event lib, that's in hindsight a design flaw I'm pretty annoyed with myself for. Given that the read logic is in the term lib, which is what's being edited, it should be possible to have that change focus though, no? (Still only one active, but hey)

@fnuecke fnuecke added this to the v1.6.0 milestone Nov 21, 2015
@fnuecke
Copy link
Member

fnuecke commented Dec 27, 2015

#1539

@fnuecke fnuecke closed this as completed Dec 27, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants