Skip to content

Implemented bubbles list widget #2

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

Closed
wants to merge 73 commits into from
Closed

Conversation

treilik
Copy link
Contributor

@treilik treilik commented Oct 6, 2020

Implemented a list widget upon the viewport-widget to view and select list items.

Its not yet able to handle strings containing words longer than the viewport width and highlighting is also not bug free.

@meowgorithm
Copy link
Member

This is cool! Let us know if you need any help with it.

sorted struct files
renamed item struct
started to add some color
rendering all items
added end of line to write lines in to new line of list
added setter // QUEST or should the fileds be public?
added Methodes for movement and selecting items
changed seperator
fixed wrap continue bug
fixed line padding errors
added NewModel function to aggregate defaults
Implemented (new) line movment functions better to
keeping curser inside the visible range
and removed unneccesary if statement
for better readability
Linebreak was inside the ansi-highlighting string and coused wired
behavier...
added simple tests for comparing View() output against a known (golden) sample
changed item wraping back to no hardwrap
changed config-Model-struct-fields to be public
so that a selected line is still distinguishable wenn color is off
and added Sort methode to apply sorting to the items of the List
to be performater created befor entering the loop
- added new test for down movement when next to curserborder.
- applied changes to test, according to previous change of line- and wrap-
prefix
- changed to not fullscreen example
- fixed offrunning curser bug through removing redundent adding of offset
- changed Up and Down to set the curser to the right place when entering
  the curserborder
and:
- reordert lineNumber() be be closer to the View
- out commented panic test because case is not handled/thought about
- implemented Methodes on list with parameter for amount of changing
- because of that the jump field gets removed
- made CurserOffset public because its config
- Implemented Lines and changed View to use Lines
- fixed Move methode to honore the Cursor-borders
- rewrote tests
- Move exampleSuffixer to suffixer.go changed other files accordingly
- removed redundant Border checks within Lines()
- changed DefaultPrefixer to mark wraped line if selected
- Added more tests, to cover the Update function and other public
  functions

- Added IsSelected to check directly selected state of index/item
- fixed bug within MarkSelected, ToggleSelect, MoveItem, GetCursorIndex
  to return OutOfBounds error when list has no items
- Changed keepVisibleWrap to set wrong targets to the nearest listend
- fixed bug within Top and MarkSelected to return errors
- added SetCursor Methode to directly move to Index
- changed structs less field to function with fmt.Stringer argument and
  changed Sort and SetLess -method accordingly

- added default case to Update in example
- commented test-keys out

- Move lineNumber to prefixer.go
- Changed Copy to copy also private Fields
@treilik treilik marked this pull request as ready for review November 16, 2020 11:57
@treilik
Copy link
Contributor Author

treilik commented Nov 16, 2020

So, after a long time, I am now happy with the code, the history and the tests for a review.
Even if there are still things i want to improve:

  • add HardWrap after it is available to fix to long lines.
  • check in the test-file, not only if error, but also for the Type of the error, if there should be an error.
  • add more (golden sample) tests and also cover more edge cases within the existing tests.
  • change example item struct to have a unique id to properly set a equals function, that don't rely on string comparison.
    If you have any thoughts or change request please do let me know.
    Cheers!

because they are public Methods to fullfill the Sort-interface
and are not allowed to return errors.

- changed example, items to have a unique ID for sorting and comparison.
- added methode within example for setting a Style for Styling the value
  of a item when calling String().
- added more/better example stringItems, so that they are more accurat.
- made example fullscreen to examplefy the CursorOffset and to show the
  multi-linebreak bug/problem.
- Changed and added key bindings to be more telling.
- added some more Methods to the list-model.
- fixed methode MoveItem to not swap with distant items but to move
  there (sadly slowly).
- changed visible default lineNumber to start at 1 rater than 0 and
  examples accordingly.
- removed, channel to print the selected items to StdOut, because if a
  panic occures the user must use 'ctrl+c' since the recieving channel
  blocks.
- added tea.Cmd to Update interface function, to be able to use other
  bubbles (i.e.: textinput) as item value.
- changed example items to be editable and added key-bindings to
  edit/change item string content and changed the example update
  function accordingly.
- added SetStyle to example to seperate the concern of style and
  content.
- Catched negative repeats in Lines() and set them to 0, not sure though
  if that is neccessary, after HardWrap is available.
to set the cursor after sorting properly.
The Set- and Get-Equals Methode of the list still are usefull,
if the user wants to get the index of a item.
The unique id within the example items are left in,
only to show how to make unique items with a proper equals function.
- Changed Lines() to be inherently bound to contain the cursor within
  the visible Lines, by starting to draw from the Cursor position.

  - because of that KeepVisible is redundant and got replaced through
    ValidIndex and validOffset, which should return the proper values
    for Cursor and lineOffset
  - lineOffset is not anymore the line offset of the current offset item
    but simple the amount of lines that should be infront of the cursor.
  - changed moving functions and test accordingly.

  - changed test to account for change of keybindings

- added minimal lineOffset to NewModel() which equals the CursorOffset,
  because if there are less items befor the cursor than the amount of lineOffset
  only the available items will get draw -> lineOffsets value is only
  valid between 0+m.CursorOffset and Screen.Height - m.CursorOffset
- added NoItems error to be able to tell difference from OutOfBounds
- changed AddItems to sort new added items, if user provided custom less
  function.
- moved default less function to be implicied within the Less function
  when there is no less function set, to be able to check if user
  provided a custom less function, within the AddItems methode.

- fixed bug within MarkSelected to use write amount after change of
  target when encountering error through ValidIndex.
- fixed bug within MoveItem to use right target index.
- returned forgotten errors within list methods

- added/changed example strings
- catched negative repeat count silently within prefixer.go because no
  logging has yet been implemented.
- renamed Move to MoveCursor to be more explicied.
- Changed UpdateItem to remove items if it returns a nil value and added
  a RemoveIndex to do this directly and dedicated.
- deleted UpdatedAllItems and UpdateSelectedItems because multi error handling,
  when the updating function returns a nil-value was cumbersome/unclear.
- changed test and example accordingly and added a key to remove (delete) and add items
- refined example strings to be more telling.

- Since a empty string gets not draw, changed the list View to return
  "empty" instead.

- Changed prefixer to not allow negative offsets since it could mess
  with the rendering of the user interface when Prefix has not enough
  space because of this.
- changed Wrap field of the list struct from bool to int, to limit the
  amount of wrapped lines per item.
- changed example strings, keybindings and tests accordingly

- changed suffix handling to not pad empty suffixes to content-width
  so one has to provide a space when all lines should be of lenght
  content-width.
- fixed lineOffset bug, to use right amount of lines.
- added config fields to list struct to make the List output fill the
  screen area, for easier horizontal/vertical combination of bubbles.
from item without effecting the cursor.

- added shortcut Method to get item under cursor
- removed redundant key binding from example
- and corrected return type to NoItems error
A selected field is better fitting on the value side from the item,
so the user has to implement and handel it if nesseccary.

- removed most of the keybindings from the Update methode,
  except basic movment. To prevent keybinding confusion.
- changed empty Lines() handling to not panic.
- changed Top and Bottom Methods to have error in case of empty list.
- implemented ResetItems to fully replace all items within the list.
- removed UnFocus Methode and changed Focus Method to take a argument.
The selected state is unnecessary within the item struct,
since its is through the fmt.Stringer interface item value easy
to implement it by one self.
to make the Lines() Methode less overfilled.
in case of to little screen area.
to signal, errors and changes within the list Model, to the caller of the Methods.
Hide (made private) Sort interface satisfying Methods because Swap would allow
silent(!) change of the list Model, this means since the Swap Method is not allowed to
return a value of type tea.Cmd we can't return a command to signify
a change of the cursor item, other changes or a (index) error.

- changed Methods to fail early and hard, so to not change the Model in
  any way if the request (-ed index) is wrong.

- rewritten top level commends.

- removed filling of the width and hight of the Lines method.
  Should be a bubbles function and not a single part of the list-bubble.

- added list-model message structs to signify a change within the list Model.

- changed/removed tests accordingly.
so that, when multiple bubbles are used they can be handled uniformly.
A error is for example necessary when the width and hight are to small
for this bubble to display properly or when the window size is not yet
known.

- changed Lines to be a **function** and a proxy to the lines
  **method**, to satisfy the elm architecture and to reduce the
  amount of **function** calls, and the associated runtime cost,
  though the copy of the Model.

- mentioned the runtime cost when adding lot of items in top level
  comment from AddItems.

- changed test-cases accordingly to change of Lines header.
to be able to change the suf- and prefix width on each item,
rather than to force a unified width for suffix and prefix per draw.

This allows for different width for each item (not line),
with the expense of performance.

Now the Init*fixer becomes a copy of the item as well as its absolute
index within the list. This seems ugly, but for a user its very
difficult to obtain a copy of the current item in a different way,
and the use of the value seems to me like a justifying use case.
I.e: a tree list with per item padding depending of the level of each
node.

- changed dependent files accordingly but crude.
- made Sort return a ListChange message since it changes the order of the
  items. This results in the possibility of a endless Sort loop, if the
  user feeds the command of the Sort make in the update and Sorts when a
  ListChange message was received. So in this case the command from Sort
  should not be feed back.
- changed name "ItemChange" message struct to "ListChange" because it
  is issued also when the order of the list changes.
- removed blocking error check in MoveCursor, which now ignores errors
  from validOffset, because a ConfigError would block the Cursor moving
  otherwise.
- updated top level comments of "hidden" sort.Interface satisfying
  methods
to be able to change Prefix of line depending according to item line
count. For example if one would like to change the prefix (or suffix)
of each last line of an item.
@@ -143,18 +115,17 @@ func TestMultiLineBreaks(t *testing.T) {
m.SuffixGen = NewSuffixer()
m.Screen = ScreenInfo{Height: 50, Width: 80}
m.AddItems(MakeStringerList([]string{"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"}))
Copy link
Contributor

Choose a reason for hiding this comment

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

Wait, WHAT??? o_O

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well, one has to test all contingencies :)
For example a item which has more lines than the screen has... dont you think?

@treilik treilik closed this Feb 9, 2021
squrki added a commit to squrki/bubbles that referenced this pull request Jun 2, 2023
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