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

CheckboxList & more Dialogs doc #889

Merged
merged 8 commits into from
May 27, 2019
Merged

CheckboxList & more Dialogs doc #889

merged 8 commits into from
May 27, 2019

Conversation

gpotter2
Copy link
Contributor

@gpotter2 gpotter2 commented May 1, 2019

Hey,

I've implemented what the TODO suggested. I've tested the code so it should work fine with existing implementations.

This PR:

  • adds CheckboxList, which has a shared implementation with RadioList
  • makes Checkbox use CheckboxList
  • adds documentation about radiolist_dialog and checkboxlist_dialog
  • adds a styling reference sheet to docs/pages/dialogs.rst to document the available styling classes + examples
  • fixes missing .run() calls in the dialog examples from the doc, as of v3.0
  • fixes typo in the doc: frame-label instead of frame.label as in the code:

style='class:frame.label',

The image linked to this example is the wrong, as one style wasn't applied :/

Demo

  • Docs usage (with style): this is overly colored on purpose, as an example on how to use the style sheet. (Yeah it's somehow ugly)

This PR:

@gpotter2
Copy link
Contributor Author

gpotter2 commented May 1, 2019

Off-topic question: how did you generate the graphics used here, for instance:

Fancy image I really wish I could generate too

Is it a plain screenshot or something fancier ? I can't get anything as fancy :/

I'd be happy to add such graphics to the part of the doc about RadioList and CheckboxList

@codecov-io
Copy link

codecov-io commented May 2, 2019

Codecov Report

Merging #889 into master will increase coverage by 0.01%.
The diff coverage is 45%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #889      +/-   ##
==========================================
+ Coverage   71.06%   71.08%   +0.01%     
==========================================
  Files         141      141              
  Lines       13378    13406      +28     
==========================================
+ Hits         9507     9529      +22     
- Misses       3871     3877       +6
Impacted Files Coverage Δ
prompt_toolkit/widgets/__init__.py 100% <ø> (ø) ⬆️
prompt_toolkit/shortcuts/dialogs.py 27.71% <16.66%> (-0.87%) ⬇️
prompt_toolkit/widgets/base.py 33.56% <48.14%> (+5.09%) ⬆️

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 eee625b...1be5b65. Read the comment docs.

@gpotter2 gpotter2 changed the title Implement CheckboxList out of Checkbox CheckboxList & more Dialogs doc May 2, 2019
@gpotter2
Copy link
Contributor Author

gpotter2 commented May 8, 2019

Hi @jonathanslenders,

Now that #880 has been merged (great job by the way !), this should be ready for reviewing.

I've rebased & re-tested everything.

@jonathanslenders
Copy link
Member

jonathanslenders commented May 11, 2019

Hi @gpotter2,

Very nice. I like what you have. There are a few remarks however I added that need to be fixed before merging. It also needs to pass mypy, except for the "_ already defined warnings".

About the screenshots, I think I used the normal Terminal application on OS X, with some changes in the settings to not display anything in the title bar. Then I used the command-shift-4 screenshot to capture the Window. This will automatically create the shadow behind the window. The screenshots were made on a retina screen with a font size sufficiently big for the quality.
[edit] I think the font in the terminal is Monaco, but not entirely sure.

@gpotter2
Copy link
Contributor Author

gpotter2 commented May 11, 2019

@jonathanslenders

There are a few remarks however I added that need to be fixed before merging.

I'm sorry, I'm not sure what you mean :/ I don't see anything
Is it a GitHub review you forgot to push ? I do that all the time 😄

Also, the tests in the last commit seem to pass, if I'm not mistaken. I made sure I followed the mypy guidance you now follow.

result: StyleAndTextTuples = [('', '[')]
result.append(('[SetCursorPosition]', ''))
class _DialogList(Generic[_T]):
class_style_container = None
Copy link
Member

Choose a reason for hiding this comment

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

These would need type annotations. Something like:

class_style_container: str = ''

or

class_style_container: Optional[str] = None

Personally, I prefer to use empty strings rather then None in this case, because an empty string is a valid style string.
An empty string is a good default for something that isn't styled.

Further, I'd like these to be renamed into:

container_style
default_style
selected_style
checked_style

The reason for that is that a style string doesn't have to contain a class name. It can contain inline styling as well, like fg:red.

multiple_selection = True


class Checkbox(CheckboxList):
Copy link
Member

Choose a reason for hiding this comment

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

I like this way of support a single Checkbox. Well done.

def __init__(self, values: List[Tuple[_T, AnyFormattedText]]) -> None:
assert self.class_style_container is not None
Copy link
Member

Choose a reason for hiding this comment

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

The four is None assertions can be removed if we use empty strings as defaults.

assert len(values) > 0

self.values = values
self.current_value: _T = values[0][0]
if self.multiple_selection:
self.current_values = []
Copy link
Member

Choose a reason for hiding this comment

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

I think current_values is only assigned here if multiple_selection is set. Mypy's not going to like that. We should always assign it, even when it's not used, and add a type annotation.

self.current_values: List[_T] = []

if self.multiple_selection:
self.current_values = []
else:
self.current_value: _T = values[0][0]
Copy link
Member

Choose a reason for hiding this comment

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

The same for current_value. It should always be assigned. (Maybe add a comment saying it's only used in case of multiple_selection.)

selected = (i == self._selected_index)

style = ''
if checked:
style += ' class:radio-checked'
style += ' %s' % self.class_style_checked
Copy link
Member

Choose a reason for hiding this comment

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

No string interpolation should be required here. The style is supposed to be a string already (mypy can check whether that's always the case).


result.append((style, '('))
result.append((style, self.class_style_open))
Copy link
Member

Choose a reason for hiding this comment

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

I think class_style_open should be called something else. Like open_character (it's not a classname).

Further, this variable should be added to the base class.

@jonathanslenders
Copy link
Member

@gpotter2, I forgot indeed to submit the review. Thanks for reminding me!

@gpotter2
Copy link
Contributor Author

gpotter2 commented May 21, 2019

Thanks for the follow up, I've updated the PR accordingly (+rebased against master)

@jonathanslenders jonathanslenders merged commit a883d0f into prompt-toolkit:master May 27, 2019
@jonathanslenders
Copy link
Member

Thank you @gpotter2, I really appreciate it!

@gpotter2 gpotter2 deleted the master branch May 27, 2019 21:21
@enbermudas
Copy link

Is there any documentation for this functionality?

@gpotter2
Copy link
Contributor Author

There is but it looks like the automated readthedocs builds have been turned off: current version "master" is pretty old

You'll have to browse it on GitHub: https://github.com/prompt-toolkit/python-prompt-toolkit/blob/master/docs/pages/dialogs.rst

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.

Question: can I have radiolist dialog where a user can select multi options? Multiple selection dialog
4 participants