Skip to content

Add scroll layout#268

Closed
salorium wants to merge 4 commits intoawesomeWM:masterfrom
salorium:layout_autoscrool
Closed

Add scroll layout#268
salorium wants to merge 4 commits intoawesomeWM:masterfrom
salorium:layout_autoscrool

Conversation

@salorium
Copy link
Contributor

I had a scroll layout :

awesomescroll

Please look at this gif for 1 minute

@psychon
Copy link
Member

psychon commented Jun 20, 2015

What exactly is your use for this? As you notice, the textbox causes some "weird things" when it tries to "make things look nice". Should we work around that for scrolling?

@salorium
Copy link
Contributor Author

I use scroll for my mpd plugin :
mpd
Gif (5 minutes duration)

@psychon
Copy link
Member

psychon commented Jun 21, 2015

That looks better than the other gif 👍

@psychon psychon modified the milestone: next: pull requests to be merged soon Jul 5, 2015
@psychon
Copy link
Member

psychon commented Jul 5, 2015

Well, this still has comments in French etc. Do you plan to do anything about that?

@firefish5000
Copy link
Contributor

I'm trying to change my awesompd as salorium has (when mixing kanji and romaji characters, nothing looks right). However, I cannot seem to figure out how to write it.
Could you give an example use case, such as how you used it with awesompd.

Also, having the timer modifiable sounds like a convenient idea to me, though the scroll() function can probably be used instead. Height scrolling seems directly related, probably just duplicating code and changing x to y unless somehow text specific (though word/char wrap make it essential).

I am hopping there is nothing overly text specific to this layout, (basically moving unconstrained widgets inside of a clipping container). I would like to know how the beginning-->end-->beginning is working(something like tiled). Can we turn that feature off and have blank space on over-scroll? If text specific, what happens with set_ellipsize("none")?

I am interested in this, but cannot seem to figure out how to call it.
I apologize if this is an inappropriate to ask questions, especially of the 'I don't get it' nature, on others pull request. If so please inform me for future reference.

@salorium
Copy link
Contributor Author

Exemple :

local wtitre= wibox.widget.textbox() 
local ctitre = wibox.widget.background()
ctitre:set_widget(wtitre)
ctitre:set_fg ("#87d7d7") 
ctitre:set_bg ("#34495e")
local titrefix = wibox.layout.scroll(ctitre,10,50)
layout:add(wibox.layout.constraint(titrefix,"max",300,nil))
wtitre:set_text("Mike Molossa via DJ Chris D - To The Top (Michael Melody Hardstyle Club Mix)")

scrollexpanded

titrefix:expand(true)

scrollexpanded1

titrefix:expand(false)

scrollspacewidth

titrefix:spaceWidth(70)

scrollspacewidth1

@firefish5000
Copy link
Contributor

Thanks for the example, works great. I did notice 1 likely bug, Short strings, ones shorter than the length of the text/scroll box or real width that is, do not seem to be properly handled.
They will scroll out, leaving nothing for a sec, and then reapear at the beginning. As can be seen with the title(top row) in the second song here
osd

Though this leaves the question if it should scroll repeating 2+ times like a tiled wallpaper does with spaceWidth between each, or stay still when all content fits.

I am currently altering the draw function to add a bouncing option(just changing deltax), and looking at the possibility of adding smooth-scroll start/stop, and vertical scrolling.(multiline text and possibly album cover)

I would love to remove the ellipse, but pango does wrapping if ellipsize=none and I cannot find a no-wrap option. Perhaps vertical scrolling will allow us to scroll the warped chars/lines out of vision. Or better yet, maybe we can lie to pango on width, and then we could have smooth scrolling on both sides, instead of 1 char appearing/dissapearing on the end.

Again, I am very pleased to have found this. I don't mind trying to fix how short strings are handled if we can establish what it should do(or if current functionality is intended), however I will not be able to look any deeper into it until next week.

firefish5000 added a commit to firefish5000/awesompd that referenced this pull request Aug 2, 2015
Scroll layout found awesomeWM/awesome#268
github repository awsomeWM/awesome pull request #268 written by salorium

This commit is just a backup in case of error before I refine the entire
awesompd. After fixing up the layout, I plan to add a Scroll_box
function which creates the textbox and scrollbox, and returns an object
with bindings for both of them(:set_text,:set_markup,:auto,:scroll,:etc)

TODO
- [x] find a way to resize text based on pixle length, not chacter count
- [x] find a way to smoothly scroll text
- [ ] title and album should be seperate scroll_boxes
- [ ] title and album scoll_boxes should be in sync (percentage scrolled
  wise)
- [ ] scroll_boxes should be capable of slowing/pausing on beginning/end
- [ ] scroll_boxes should be capable of slowing/pausing incrementilly
- [ ] scroll_boxes should be capable of "bouncing" left and right.
- [ ] Find a way to shorten text the same way pango does with ellipsize
  to fit the widgit, without having an ellips.
@salorium
Copy link
Contributor Author

Hmm "This branch has conflicts that must be resolved", where ?

@blueyed
Copy link
Member

blueyed commented Aug 19, 2015

@salorium
You need to rebase it on master, then you'll see them.

@salorium
Copy link
Contributor Author

@blueyed Thank you 👍

@salorium
Copy link
Contributor Author

Hello,
I have a bug with Master update :
if base.place_widget_at( self.widget,-105 , 0,width-10,height)
Options -105 overload :
15-09-2015 18 17 13

@blueyed
Copy link
Member

blueyed commented Sep 15, 2015

@salorium
Can you git-bisect to a specific commit on master?
Is it that negative indices break it / are not supported anymore?

@salorium
Copy link
Contributor Author

@blueyed :
commit => 2330040
The negative values are always accepted, but before it did not draw on top of other widget
15-09-2015 18 17 13

@psychon
Copy link
Member

psychon commented Sep 15, 2015

Previously children were clipped to the size of their parent. Elv13 wants widgets to be able to draw outside of that, so they now can do that. Add a new function:

function scroll:before_draw_children(context, cr, width, height)
  cr:rectangle(0, 0, width, height)
  cr:clip()
end

Note that this only clips the drawing. For input (mouse clicks), the widget will still be considered to have the larger size.

@salorium
Copy link
Contributor Author

@psychon : Thank you, it work
For input :
I can move event mouse clicks of the widget on scroll layout ?
Or forcing event just to the visible area (0 - width) ?

@psychon
Copy link
Member

psychon commented Sep 16, 2015

Would it be ok to you if I were to rewrite this and do it slightly differently? (Instead of using :layout() to draw things, I'd draw the widget to an image surface and then can scroll things really efficiently)

For this, I'd like to hear your input about what exactly this thing should do.

First, am I right in that :set_expand(true) just makes the widget to be drawn to a larger size than what it requested via :fit()? Without :set_expand() this space would stay empty.
The widget works by updating an offset each time seconds by adding deltax to it. space is the size in pixel of some extra space that basically describes a distance between the end of the widget and the next beginning of it. Finally, width specifies a maximum size for this scrolling widget and if autoscroll is false, then :scroll() has to be called somehow externally (no timer is started for this). In :fit(), the scroll layout behaves like the "child widget", but restricts the width to the width.

Does this describe your scroll layout?

@salorium
Copy link
Contributor Author

@psychon :

Would it be ok to you if I were to rewrite this and do it slightly differently?

Yes, you can

First, am I right in that :set_expand(true) just makes the widget to be drawn to a larger size than what it requested via :fit()? Without :set_expand() this space would stay empty.

Yes

The widget works by updating an offset each time seconds by adding deltax to it.

Yes

space is the size in pixel of some extra space that basically describes a distance between the end of the widget and the next beginning of it

Yes

Finally, width specifies a maximum size for this scrolling widget and if autoscroll is false, then :scroll() has to be called somehow externally (no timer is started for this).

Yes

In :fit(), the scroll layout behaves like the "child widget", but restricts the width to the width.

Yes

If the width of widget < width of scroll layout. The widget is not scrolling :

if self._wg ~= wg  then
            self._x = 0
            if self._scrolltimer.started then
                self._scrolltimer:stop()
            end
        end

Here I disable autoscroll (widget update exemple :set_text() for textbox)

if self._wg > width then
        if self._scrolled and not self._scrolltimer.started then
            self._scrolltimer:start()
        end
    end

I enable autoscroll, if the width of widget self._wg > width of scroll layout width

@psychon
Copy link
Member

psychon commented Sep 17, 2015

Ok, here is a first version: https://gist.github.com/psychon/2ff6cebbdf05c012351c
In contrast to the version in this PR, this draws the scrolled widget to a cairo.ImageSurface and thus can do scrolling quite efficiently (the widget itself doesn't have to redraw itself). Also, this approach avoids the "stuttering effects" that we get from the textbox.

Another difference is that this gets a frames-per-second argument instead of the timeout directly. "20 fps" just looks better to my eyes than "redraw every 0.05 seconds".

I was lazy and didn't write any setters yet. The step_function is a nice little trick so that we can do more than just "scroll from right to left and repeat".
An example you should definitely try out:

local scroll = require("wibox.layout.scroll").horizontal(widget, 20, 30, 10, true, 50, function(elapsed, size, visible_size, speed, extra_space)
        size = size + extra_space
        local state = ((elapsed * speed) % (2 * size)) / size
        local negate = false
        if state > 1 then
                negate = true
                state = state - 1
        end
        if state < 1/5 or state > 4/5 then
                state = state < 1/5 and 0 or 1
        else
                state = (state - 1/5) * 5/3
                if state < 1/3 then
                        state = 2 * state * state
                elseif state < 2/3 then
                        -- state = 1/3, result = 2/9
                        -- state = 2/3, result = 7/9
                        state = 5/3*state - 3/9
                else
                        state = 1 - 2 * (1 - state) * (1 - state)
                end
        end
        if negate then
                state = 1 - state
        end
        return (size - visible_size) * state
end)

All arguments are optional and CPU usage seems to be insignificant.

Comments on this? Is this ok for you and can this to about everything your version does?

@salorium
Copy link
Contributor Author

@psychon
Copy link
Member

psychon commented Sep 20, 2015

Sorry for the broken first version, should be fixed.

@psychon
Copy link
Member

psychon commented Nov 22, 2015

Here is a new version of my scroll layout: https://gist.github.com/psychon/2089ff521a51d9f2c77f
However, I came up with a new (better?) idea on how to implement this. Sorry & please be patient with me. (This will also fix the background problems with the current version)

@psychon psychon mentioned this pull request Nov 22, 2015
@psychon
Copy link
Member

psychon commented Nov 22, 2015

My newest version is available in #571. It should be a little slower than what I posted in my last comment, but its memory usage should be better (since it doesn't cache an image of what is drawn).

I hope everyone is ok with my version.

@blueyed
Copy link
Member

blueyed commented Dec 12, 2015

Merged now through #571.

@blueyed blueyed closed this Dec 12, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants