-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
[GUI] Better event filtering system #801
Conversation
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
python/taichi/misc/gui.py
Outdated
@@ -123,30 +123,53 @@ def line(self, begin, end, radius, color): | |||
self.canvas.path_single(begin[0], begin[1], end[0], end[1], color, | |||
radius) | |||
|
|||
def show(self, file=None): | |||
def show(self, file_or_image=None): |
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.
how about having two args: file
and image
? Then users can both show it and save it as files
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.
I would suggest them:
gui.set_image(image); gui.show(file)
.gui.show(); ti.imwrite(image, file)
.
I prefer 2, since I think show(file) is just a backward-compat-deprecated API. With ti.imwrite
, users can even save images without GUI, provides more flexibility.
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.
Then i think this should just be image
, because imwrite
is already able to save to files? Again, if you think at the API layer, GUI is supposed to deal with one thing -- GUI. And we have separate APIs for file writings. WDYT?
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.
First of all, this part does not belong to the event filtering system. Please revert.
Please understand that having too many things in a PR makes reviewing really hard since the discussions cannot be focused on the real thing. This also increases the delay in merging your contribution since there are too many to discuss, and will result in nasty merge conflicts.
My thoughts on this specific issue: I agree that ti.GUI.show
should not provide the option to write to disk. We might still need an API to get the image from the GUI or save the GUI image to disk, since sometimes people use drawing commands such as ti.GUI.circles
to paint, and the painted result is only available from the GUI. Maybe we should do
gui.set_image
to set a background image and allow people to paint on itgui.show(image=None)
to show the current canvas, or a plain 2D image (ifimage
not none). Clear the temporary canvas after window content is updated.gui.screenshot(filename=None) -> np.ndarray
return the canvas. Iffilename
is notNone
, useimwrite
to save to disk.ti.imwrite(gui.screenshot(), 'X.png')
sounds slightly verbose so I think a shortcut would be good.
The API design here should be put into a separate issue.
python/taichi/misc/gui.py
Outdated
break | ||
return True | ||
|
||
def get_key_event(self): | ||
def get_cursor_pos(self): # ABi |
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's ABi
?
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.
get_cursor_pos
is an alias of self.core.get_cursor_pos
, which is in C++ scope, so it's an ABI.
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.
hmm, feels a bit redundant, but sounds good
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.
Sorry but I'm still confused about this: does ABi
here stand for Application binary interface? Why is i
lowercased here?
Sorry for the late response.. |
Btw, do we have some deprecated function need to be marked as deprecated? Like |
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.
Sorry for my late response recently... I'm following this tutorial http://www.realtimerendering.com/raytracing/Ray%20Tracing%20in%20a%20Weekend.pdf and writing a toy ray tracer on Metal these days... I believe it also offers me insights of how to use/improve Taichi (For example, I just found out that Metal doesn't support recursion function calls!)
python/taichi/misc/gui.py
Outdated
@@ -123,30 +123,53 @@ def line(self, begin, end, radius, color): | |||
self.canvas.path_single(begin[0], begin[1], end[0], end[1], color, | |||
radius) | |||
|
|||
def show(self, file=None): | |||
def show(self, file_or_image=None): |
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.
Then i think this should just be image
, because imwrite
is already able to save to files? Again, if you think at the API layer, GUI is supposed to deal with one thing -- GUI. And we have separate APIs for file writings. WDYT?
Ok, now the API becomes: |
|
I'll just leave this to @yuanming-hu to decide the API changes. In general, I think there are a few things.
|
Yes, it did get confusing... let's just merge the first commit in this PR? |
This comment has been minimized.
This comment has been minimized.
Sorry I have meetings until early afternoon. I'll take care of this thread later today. Thanks for being patient and for the valuable discussions here. |
Oh this tutorial is cool! Have fun!
Interesting, so does GLSL... Seems most modern shader langs don't support recursion for simplicity, how about CUDA? And that may explain why simple ray tracers usually use CPU... hopefully taichi could change this role :) |
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.
Hello? I thought I made a good PR description...
The description is indeed well-written. Good job! Sorry I've got too many things to do recently do my review might be delayed.
你没有阻止我那样做,甚至还对那些顺手牵羊的代码做了一些改进建议...
No need to be rude here. It should be the PR authors' (not reviewers') duty to prevent PRs from getting big. After all, reviewers cannot stop PR authors from adding unrelated commits. The only thing reviewers can do to keep development in order, is refusing to review/merge PRs with unrelated changes. I also highly recommend a re-reading of https://github.com/yuanming-hu/public_files/blob/master/graphics/taichi/google_review_comments.pdf
I'll continue my review after existing comments are addressed.
python/taichi/misc/gui.py
Outdated
break | ||
return True | ||
|
||
def get_key_event(self): | ||
def get_cursor_pos(self): # ABi |
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.
Sorry but I'm still confused about this: does ABi
here stand for Application binary interface? Why is i
lowercased here?
python/taichi/misc/gui.py
Outdated
e = self._peek_key_event() | ||
return e | ||
|
||
def get_key_event(self): # Unique APi |
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.
Again, if APi
stands for application programming interfaces, why is i
lowercased?
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.
For fun :)
python/taichi/misc/gui.py
Outdated
@@ -123,30 +123,53 @@ def line(self, begin, end, radius, color): | |||
self.canvas.path_single(begin[0], begin[1], end[0], end[1], color, | |||
radius) | |||
|
|||
def show(self, file=None): | |||
def show(self, file_or_image=None): |
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.
First of all, this part does not belong to the event filtering system. Please revert.
Please understand that having too many things in a PR makes reviewing really hard since the discussions cannot be focused on the real thing. This also increases the delay in merging your contribution since there are too many to discuss, and will result in nasty merge conflicts.
My thoughts on this specific issue: I agree that ti.GUI.show
should not provide the option to write to disk. We might still need an API to get the image from the GUI or save the GUI image to disk, since sometimes people use drawing commands such as ti.GUI.circles
to paint, and the painted result is only available from the GUI. Maybe we should do
gui.set_image
to set a background image and allow people to paint on itgui.show(image=None)
to show the current canvas, or a plain 2D image (ifimage
not none). Clear the temporary canvas after window content is updated.gui.screenshot(filename=None) -> np.ndarray
return the canvas. Iffilename
is notNone
, useimwrite
to save to disk.ti.imwrite(gui.screenshot(), 'X.png')
sounds slightly verbose so I think a shortcut would be good.
The API design here should be put into a separate issue.
Fully reverted, only event filtering preserved! |
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.
Thanks for taking the suggestions!
AppVeyor failed due to network reason again:
|
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.
LGTM (with one nit)
Personally I think the OR semantics is more intuitive than AND. There could be several open-ended questions regarding AND:
1.Since currently we don't check the tuple size, in theory a user could pass in an AND tuple with a size larger than 2. E.g. (TI.RELEASE, TI.ESCAPE, TI.SPACE)
. Should we disallow this? Or should we consider supporting it in the future?
2. If we do, then are (TI.RELEASE, TI.ESCAPE, TI.SPACE)
and (TI.RELEASE, SPACE, TI.ESCAPE)
equivalent, or even (TI.SPACE, TI.RELEASE, TI.ESCAPE)
?
That said, I think this PR is good enough.
return False | ||
|
||
def get_events(self, *filter): | ||
filter = filter and GUI.EventFilter(*filter) or None |
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.
I know I suggested filter or None
, but in this case, i think the idiomatic way is GUI.EventFilter(*filter) if filter else None
.
Thank for purposing this, but we won't support this. Why can a event be both ESC and Space? There is only one key pre-event, no multiple keys, if they want, they use |
Postponed by #839. |
Added doc! |
Related issue = #... (if any)
[Click here for the format server]
We used to support filter by only
type
.Now we also support filter by
key
, or by(type, key)
combination.by key:
by key + type:
by comb: