This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
PixelFox's profile picture

How would one make windowed programs

Started by PixelFox, 03 July 2015 - 09:40 PM
PixelFox #1
Posted 03 July 2015 - 11:40 PM
My goal is to resize a program, that's all I need, and maybe a border.
How would I do that, I know it's possible, I've seen LyqydOS, but,
I'd like to know the command to do it. I have a huge OS right now
(And there's no use in showing you it)
And I want to know the command for resizing the program…
Or maybe it isn't as simple as I hoped it'd be (I'd probably make an
API)
Bomb Bloke #2
Posted 04 July 2015 - 01:45 AM
I'm afraid there isn't "a" command for this. Just to deal with mouse-clicks you'd want a custom coroutine manager.

But the "simple" method (relative to most any other method, at least) would be to make use of the window API, which provides you with buffered terminal objects that you can redirect your scripts to. Windows can be easily moved and resized. The idea would be to use two windows per script, one the parent of the other - the child would be full-sized at all times, and the parent you can move around and resize. Resizing a window to a smaller size causes it to discard any content that's being cropped out, but since resizing a parent doesn't cause the child to lose information, that ceases to be a problem (you simply redraw the child whenever you enlarge the parent, and boom - the content's back).

Of course, a dedicated buffer object (one tailor-made for your purposes) would be more efficient in terms of speed, but the window API is very handy as a "one size fits all"-type solution.
PixelFox #3
Posted 04 July 2015 - 01:54 AM
I'm afraid there isn't "a" command for this. Just to deal with mouse-clicks you'd want a custom coroutine manager.

But the "simple" method (relative to most any other method, at least) would be to make use of the window API, which provides you with buffered terminal objects that you can redirect your scripts to. Windows can be easily moved and resized. The idea would be to use two windows per script, one the parent of the other - the child would be full-sized at all times, and the parent you can move around and resize. Resizing a window to a smaller size causes it to discard any content that's being cropped out, but since resizing a parent doesn't cause the child to lose information, that ceases to be a problem (you simply redraw the child whenever you enlarge the parent, and boom - the content's back).

Of course, a dedicated buffer object (one tailor-made for your purposes) would be more efficient in terms of speed, but the window API is very handy as a "one size fits all"-type solution.
Could you make an example? That'd be all I'd need to make my API, maybe like
an edit window, or if not, that's fine, I'll try to figure it out.
Gumball #4
Posted 04 July 2015 - 02:48 AM
I'm afraid there isn't "a" command for this. Just to deal with mouse-clicks you'd want a custom coroutine manager.

But the "simple" method (relative to most any other method, at least) would be to make use of the window API, which provides you with buffered terminal objects that you can redirect your scripts to. Windows can be easily moved and resized. The idea would be to use two windows per script, one the parent of the other - the child would be full-sized at all times, and the parent you can move around and resize. Resizing a window to a smaller size causes it to discard any content that's being cropped out, but since resizing a parent doesn't cause the child to lose information, that ceases to be a problem (you simply redraw the child whenever you enlarge the parent, and boom - the content's back).

Of course, a dedicated buffer object (one tailor-made for your purposes) would be more efficient in terms of speed, but the window API is very handy as a "one size fits all"-type solution.
Could you make an example? That'd be all I'd need to make my API, maybe like
an edit window, or if not, that's fine, I'll try to figure it out.

Keep in mind, the program will have to be able to resize.
Easy fix if your program puts pixels down according to the current terminals width and height

Something like this (I dont know if this will work but it should be something close to this):

programParent = window.create(term.current(),1,1,width you want,height you want)
programChild = window.create(programParent,1,1,w,h)

cornerX,cornerY = [width you want], [height you want]
topX,topY = 1,1

program = coroutine.create(loadfile([path of program you want here]))

term.redirect(programChild)

while true do
  local event, p1, p2, p3 = os.pullEvent()
	coroutine.resume(program,event,p1,p2,p3)
	if(event == "mouse_click") then
	  type,X,Y = p1,p2,p3
	  if(X == cornerX and Y == cornerY) then
		_,cornerX,cornerY = os.pullEvent("mouse_up")
		programParent.reposition(topX,topY,cornerX,cornerY)
	  elseif(X >=topX and X <= cornerX and Y == topY) then
		_, topX, topY = os.pullEvent("mouse_up")
		programParent.reposition(topX,topY,cornerX,cornerY)
	  end
	end
end

If you use this, please give me credit :)/>

Edited the code so coroutine doesn't have "events" be nil, it returns the event, p1,p2,p3 so that fixes SOMETHING. (In the many flaws that program probably has.)
Edited on 04 July 2015 - 06:15 PM
Bomb Bloke #5
Posted 04 July 2015 - 03:35 AM
Keep in mind, the program will have to be able to resize.
Easy fix if your program puts pixels down according to the current terminals width and height

Something like this (I dont know if this will work but it should be something close to this):

Er, something like that, yes. In particular your coroutine-handling code is quite busted… but so are most other attempts I see at that kind of thing. You've more or less covered the basic idea though.

Another thing, the joy of using two windows is that the script the "OS" is managing does not need to handle terminal resizing. The OS can resize the parent all it likes, and the actual terminal the script is using - the child - won't be affected. It's just a matter of calling programChild.redraw() immediately after every programParent.reposition() call to get the correct imagery back on screen. :)/>

Of course, it may be that you don't want to hide resizes from the scripts in this manner; in that case, you'd only use the one window. That's a matter of taste. Given that most scripts don't handle terminal resizing, I say you're better off hiding it.
Edited on 04 July 2015 - 01:43 AM
Lyqyd #6
Posted 04 July 2015 - 03:40 AM
Most scripts can at least handle adjusting to the current size when they're started, so one could usually adjust the window size and re-launch the program if you expose the actual size to the program. That's the option used in LyqydOS, and it works pretty well. Not fantastically, of course, but fairly well.
Gumball #7
Posted 04 July 2015 - 08:14 PM
Keep in mind, the program will have to be able to resize.
Easy fix if your program puts pixels down according to the current terminals width and height

Something like this (I dont know if this will work but it should be something close to this):

Er, something like that, yes. In particular your coroutine-handling code is quite busted… but so are most other attempts I see at that kind of thing. You've more or less covered the basic idea though.

Another thing, the joy of using two windows is that the script the "OS" is managing does not need to handle terminal resizing. The OS can resize the parent all it likes, and the actual terminal the script is using - the child - won't be affected. It's just a matter of calling programChild.redraw() immediately after every programParent.reposition() call to get the correct imagery back on screen. :)/>

Of course, it may be that you don't want to hide resizes from the scripts in this manner; in that case, you'd only use the one window. That's a matter of taste. Given that most scripts don't handle terminal resizing, I say you're better off hiding it.

Yeah, I know the coroutine handling isn't that good, I just wanted to have to do whatever it needs to whenever os.pullEvent is triggered. I'm better at coroutines than that.