-
Notifications
You must be signed in to change notification settings - Fork 54
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
Detect file changes #135
base: master
Are you sure you want to change the base?
Detect file changes #135
Conversation
app/window.py
Outdated
self.host = host | ||
self.controller = app.cu_editor.PopupController(self) | ||
self.setTextBuffer(app.text_buffer.TextBuffer()) | ||
self.controller.setTextBuffer(self.textBuffer) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
consider overriding setTextBuffer and set the controller.setTextBuffer there. It doesn't make a big difference right now, but maybe in the future: if if setTextBuffer is called it should tell the controller.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, sounds good.
#profile = app.profile.beginPythonProfile() | ||
if message == 'quit': | ||
app.log.info('bg received quit message') | ||
return | ||
elif message == 'popup': |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can the pop-up simply be a top level modal window in the ci_program.py zOrder, so that background.py wouldn't need to know anything about it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you mean by this? I'm making it so that the FileStats object contacts the background thread, and the background thread contacts the main thread. Right now background.py doesn't really know anything about the pop-up and it's just redirecting it to the main thread.
3261263
to
216c5ac
Compare
@@ -0,0 +1,211 @@ | |||
import app.background |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need a copyright comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
8a3f3bd
to
362b8a3
Compare
Sorry for the slow feedback (on my part) for this PR. I'll try to get more time with it this evening or Monday. |
No worries! I've been taking a break from this PR because I just couldn't figure out the synchronization issue. Maybe I'll be able to give it another go this weekend. Essentially the bug that is occurring is that sometimes, the popup window will not render on the screen, but the focus has changed to it. It will show up on the screen if any key is pressed (thus refreshing the screen and making it display). This could be troublesome because if the user types Y, they could accidentally reload the text file and lose all their current changes. |
WDYT of separating the popup window to another PR (that would make reviewing it easier) |
I could do that. It just seemed incomplete if I were to move the popup out of this PR and also I needed to test it using the popup, so I bundled them up together. I'll see if I can separate it out. |
362b8a3
to
8561c27
Compare
…n file. Need to integrate this into the program
… refresh the TopInfo window, but doesn't seem to be displaying in the program
…nction in background.py. Also renamed refresh to redraw
…e program needs, which will prevent synchronization issues from occurring. Saving redo chain has now broken and needs to be fixed and still need to support fileStats when in singleThread mode
…n for single-threaded version
…in multithreaded mode. Also renamed getTrackedFileInfo to getUpdatedFileInfo to better reflect its functionality
…ck to the loadTextBuffer() function
…Stats object so that it will track the new file. Also created a FileTracker object that inherits from threading.Thread in order to speed up the killing of threads.
… which would check if the file on disk has changed
…igure out how to render this window
8561c27
to
4ec9d8e
Compare
I've just updated this to work with the new master branch |
@dschuyler Do you think there are any functionality changes that need to be made? It currently polls the file every ~2 seconds, but I don't think each poll has a lot of overhead. There's still that one synchronization bug, but I still have yet to figure out why it's happening. |
On Linux machines (and WSL), we can use |
I looked into a different platform called |
@dschuyler are we moving away from using the Window.hide() function now? I see that there is now an |
Yes, Window.hide() is transitioning. I had hide/show removing or adding the window to the parent. At the moment, detach()/reattach() play a similar role. I'm up for suggestions on what to call these things. The concept I'm trying to name is one where:
|
I actually have a question regarding the format of the program. From what I understand, inputWindow is everything we see on the screen when we start up the program. This window contains a text buffer (which is where we display the file and type into the file), just like all other windows. However, this window also contains other windows like labeledLine, and lineNumbers. Then, there is the programWindow which essentially contains the high level windows like inputWindows, palletteWindows, debugWindows, etc. I am guessing that when we decide to support split screen, we'll have multiple inputWindows? This programWindow also controls the zOrder and layering of all these high level windows. I don't think the inputWindows control or need to control any of its own windows. Do I have the general idea correct? |
Yes-ish. Think of Windows being in a hierarchy. The top-most window (or root window) is a ProgramWindow window.
Yes, though all of that is within the ProgramWindow, but the ProgramWindow doesn't have any UI of it's own. ProgramWindow could have UI, it just doesn't. It's used as a container to stick other windows into.
Yes.
Yeah, that's the idea.
Yeah. Actually every window can have child windows. The
I don't understand what this is saying, sorry. Could you say or ask this in another way?
Sounds like it, though I'm not sure on that last one. |
Trivia: Initially ci_edit didn't have a ProgramWindow. I was using the CiProgram as the topmost window. That got weirder and more cumbersome over time. Eventually I created ProgramWindow to give a cleaner top-level window and a cleaner separation between CiProgram and the window hierarchy. I'm glad I did. It's been helpful. So there should only every be one ProgramWindow and it mainly exists to keep the code organization cleaner. |
Bonus: I printed out a hierarchy for ci_edit when it's first started and annotated what the pieces are:
[edit: I'd mislabeled/omitted the right column view and TopInfo.] |
Oh what I meant was just that I thought it would have been better to have all the painting and layering done by the programWindow and not the inputWindow as well, but now I'm thinking each window should control its own subwindows to make it easier (like what we have right now). |
Also, what do you think about making some variables global, or adding a reference to the programWindow to all windows when initialized. I find that if I want to get access to the programWindow, or the popup window, I sometimes would have to do |
How about a global object |
I'd like to avoid globals (even though I use them at times). Can the desired effect be done with this paradigm
|
P.S. I also agree that |
@dschuyler How about constructing |
For example: |
I'm not 100% sure I understand, sorry. New note about Lately I've been thinking that Goals: I'm looking for a solution that
What is in ci_edit right now does not reach those goals (my fault, it's something I'm working on fixing). |
Thanks, I'll think on that more. |
Would we have one inputWindow per file open / per view of a file open? I think this would make supporting multiple files easier since we wouldnt have to worry about switching out text buffers and resetting all the windows. We can maybe store all open files as "inputWindow“s in memory. The program window can have a list of inputWindows to display, as well as a list of open but inactive (not being displayed) inputWindows (files/views). The program window can then have pre defined formatting for displaying 1 or 2 inputWindows, which can just be what we have right now, or split screen. I also imagine having a "tabs" section (maybe a subwindow in programWindow) that shows open windows. Changing tabs would just mean swapping the programWindows displayed inputWindows with the clicked one. Im thinking that we could make most windows recursively ask their parent for an action to occur, just as you mentioned before. This would solve the references for an ancestor N levels above. |
Just some notes that will hopefully clarify the current intent. For open files and InputWindows the intent is to allow for many open TextBuffers and many InputWindows. Any given InputWindow will have exactly one TextBuffer. If there are no open TextBuffers from disk, an empty (new) TextBuffer is created for the InputWindow. A TextBuffer can exist without an InputWindow. E.g. a TextBuffer can be loaded, manipulated, and written back to disk without ever appearing in an InputWindow (this doesn't currently happen, but the design is that it could be done). The TextBuffer that an InputWindow is looking at can be changed (this happens every time a new file is viewed without quitting the editor, since there's only one InputWindow currently)*. In the future, there may be many InputWindows. Any InputWindow may be viewing any of the TextBuffers. Two or more InputWindows may be using the same TextBuffer. Edits made in either InputWindow will appear in the other. If tabs are implemented*, the TabRowWindow (or whatever it may be called) would likely be a child of the ProgramWindow. The InputWindows may be either siblings of the TabRowWindow (makes sense if there is a single tab controller); or they may be children of a TabRowWindow (makes sense if there may be multiple tab controllers). *The currently viewed TextBuffer within an InputWindow can be changed with ctrl+p. |
Right, so for right now, should we look towards refactoring a bit to support this paradigm? If we are going to change the hierarchy and relationships between windows, it would be easier to do it earlier than later. Maybe for now we can do something like the following:
This would make it easier to:
Also one more thing. Should we add the inputWindow's textBuffer into its own window (FileContentWindow)? It seems like the text buffer object is just floating around in the inputWindow while being surrounded by other windows, though I don't know how necessary this new window would be. |
This is my current goal (though the code isn't there yet)
My hope is that passing messages up parent to parent will alleviate the need for asking for the program window or input window. |
So our paradigm is the Mediator Pattern, isn't it? The Polymer docs phrase it like this:
|
Yes that's the paradigm I'm following. I'm trying to work a bit on refactoring this. |
I don't know if we can follow that exactly. The hierarchy looks something like this right now
Some windows need to reference the textBuffer object under InputWindow, and then need to make a function call. However, calling textBuffer.function() would violate the relationship paradigm since they don't have direct access to the buffer. We could make functions in inputWindow that call these functions, but then that would also need to propagate throughout the tree, and we would need a huge amount of extra functions. We could maybe make the textBuffer a shared resource throughout all windows under inputWindow, by passing it into the constructor of every window, which would allow us to avoid this. |
Very good point indeed. Now that I think about it, we might want to have more than one tree...
|
Yes. In some GUI frameworks words like Window, View, Facet, Surface, and Pane have distinct meaning. The ci_edit GUI hasn't progressed far enough to make distinct meanings. So at the moment they are rather interchangeable. This is a flaw, though; I we should define them.
Yes (or it may be None). |
This PR includes a new object in the TextBuffer object that tracks the file on disk using threads. If in single-threaded mode, the object will not automatically track the file, but can be used to manually grab the information from disk.
So far, this thread sends requests to the background thread in
background.py
to notify the main thread to do things. So far, the thread will detect if the file is "Read Only", and if the file has changed since it was last saved/opened. If the file was changed since it was last saved/opened, a popup box will appear, asking the user if they would like to reload the file. For some reason, there is a bug somewhere which is causing the popup box to not appear the screen refreshes again, but I'm putting this PR up to just get some input for now, as I work on it some more.I made the popup box so it made it easier to see for the user to see, and I figured we could also make other important messages appear in this box, like saving or overwriting a file.