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

DataView Image channel #683

Merged
merged 7 commits into from
Aug 25, 2020
Merged

DataView Image channel #683

merged 7 commits into from
Aug 25, 2020

Conversation

corranwebster
Copy link
Contributor

@corranwebster corranwebster commented Aug 21, 2020

This adds an image channel to the DataView.

This currently uses IImageResource objects and Image traits, which is good enough for many use cases, but not completely generic. Eventually we would like some sort of dynamic image object to be able to be used, but that is orthogonal to the PR.

Currently only supported in Qt. Wx support is possible, but not attempting for now.

@codecov-commenter
Copy link

codecov-commenter commented Aug 21, 2020

Codecov Report

Merging #683 into master will increase coverage by 0.09%.
The diff coverage is 76.47%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #683      +/-   ##
==========================================
+ Coverage   39.23%   39.33%   +0.09%     
==========================================
  Files         491      491              
  Lines       26936    26968      +32     
  Branches     4073     4079       +6     
==========================================
+ Hits        10569    10608      +39     
+ Misses      15904    15901       -3     
+ Partials      463      459       -4     
Impacted Files Coverage Δ
pyface/ui/qt4/data_view/data_view_item_model.py 47.64% <22.22%> (-1.43%) ⬇️
pyface/data_view/abstract_value_type.py 96.55% <88.88%> (-3.45%) ⬇️
pyface/data_view/value_types/constant_value.py 100.00% <100.00%> (ø)
pyface/data_view/value_types/no_value.py 100.00% <100.00%> (ø)
pyface/ui/wx/data_view/data_view_model.py 55.96% <100.00%> (-0.41%) ⬇️
pyface/ui/qt4/console/console_widget.py 29.28% <0.00%> (+0.20%) ⬆️
pyface/ui/qt4/code_editor/code_widget.py 44.16% <0.00%> (+0.84%) ⬆️
pyface/wx/python_stc.py 10.36% <0.00%> (+1.21%) ⬆️
pyface/ui/wx/window.py 77.10% <0.00%> (+2.40%) ⬆️
pyface/ui/qt4/util/gui_test_assistant.py 80.53% <0.00%> (+2.65%) ⬆️
... and 1 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update ae60ae2...bf3eafd. Read the comment docs.

Copy link
Contributor

@kitchoi kitchoi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly LGTM, two minor questions.

@@ -182,6 +182,50 @@ def set_text(self, model, row, column, text):
"""
raise DataViewSetError("Cannot set value.")

def has_image(self, model, row, column):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On naming... I notice that this is the same naming in the TableEditor / ListStrAdapter / etc. (https://github.com/enthought/traitsui/search?q=get_image&unscoped_q=get_image)
This image gets used with the DecorationRole, which is for displaying an icon or color (e.g. a color square next to the text).

Given the new data view is supposed to be more flexible, e.g. it needs to support alternative editors in the cell such as a spinbox or a combobox, we probably want to differentiate an icon that accompanies the rest of the cell from an image that fills up the entire cell. Since this is new code, could we name this has_icon and get_icon instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a distinction in most backends between an image and an icon - an icon is a collection of related images with different styles (ie. versions for enabled/disabled, highlighted, activated, etc.). This is very much not an icon in this sense, and Pyface has no object which corresponds to an icon (IImageResource tries to be both an image and an icon and fails at both). So these method as written are very much a "image"-based.

Let's leave this as-is for now, since this is currently the only way to display image data; we might revise when it comes time to implement custom editors/renderers and provide a separate channel for icon-like image collections.

Also note that Qt decorations are not limited to icons, and can potentially display thumbnails or even full images (as well as colors).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay. Just trying to say that as someone reading this method's docstring, it is not obvious that it is used as a decoration rather than an image filling up the whole cell. It was a bit of a surprise that the editable value is used alongside this image.

Qt documentation is very specific about what DecorationRole means:

The data to be rendered as a decoration in the form of an icon. (QColor, QIcon or QPixmap)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you have a large image and no text, the decoration will fill up the whole cell (or most of it - I think there may be a border, and you have to take into account how cell sizes are determined).

As someone writing an implementation of this method, you shouldn't care how this image is being displayed; you are providing some image data, and it is up to the view to determine what to do with it.

-------
image : IImageResource or None
The image associated with the underlying value, or None if there
is no image.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This None if there is no image is making me wonder why we have has_image at all. Can we just let has_image does the filtering so this get_image does not have to worry about no images? Otherwise it is a bit like having two ways to do the same thing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is mainly for simple synchronicity with the other data channels (has_text, get_text, has_tooltip, get_tooltip etc.) consistent APIs are lower cognitive overhead. But thinking about it, None probably shouldn't be an allowed return value.

Note that I am considering an add-on PR which will allow returning a PIL/Pillow Image in addition, but that's orthogonal.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not allowing None as a returned value sounds good to me.

if value_type.has_image(self.model, row, column):
image = value_type.get_image(self.model, row, column)
if isinstance(image, IImageResource):
return image.create_image()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Observation, not a request change: Here to more untested code, but this entire module is untested and supposed to be rewritten.
I don't see an issue opened for rewriting this and getting it covered with tests, did I miss it or should I open it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a lot of things that don't have issues yet on the dataview roadmap. This is one of them.

@corranwebster corranwebster merged commit f9cd8fd into master Aug 25, 2020
@corranwebster corranwebster deleted the feat/data-view-images branch August 25, 2020 10:52
@corranwebster
Copy link
Contributor Author

Note: partially resolves #533

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

Successfully merging this pull request may close these issues.

3 participants