10

Recently I've seen this widget in Gedit:

enter image description here

It appears when you press Ctrl + F. What I am interested is in how to get the sliding effect. Any suggestion will be appreciated.

David Planella
  • 15,420
  • 11
  • 77
  • 141
Ángel Araya
  • 1,542
  • 1
  • 11
  • 23
  • Not Understand Sliding effect clarify what "sliding effect means " – twister_void Sep 07 '12 at 15:49
  • @Gaurav_Java it appears sliding from below the top panel. If you see it in Gedit you'll see it pressing 'Ctrl + F' – Ángel Araya Sep 07 '12 at 19:19
  • The effect is often called "drop-down", I believe - sometimes menus are animated in the same way. – Steve Kroon Sep 09 '12 at 10:11
  • @SteveKroon All I find is about ComboBoxes and not useful with other widgets. I think. – Ángel Araya Sep 09 '12 at 20:32
  • 1
    I thought maybe you could use a css transition property, but I don't see how to change positioning in css. Looking through the gedit code, they seem to use a custom viewframe to for the search box http://bazaar.launchpad.net/~vcs-imports/gedit/master-git/view/head:/gedit/gedit-view-frame.c which they animate through some theatrics module (look at the bzr). I'm not very good at parsing C code though. – Ian B. Sep 10 '12 at 00:27
  • 1
    BTW, this widget is also in Google Chrome (and Chromium presumably) – Ian B. Sep 10 '12 at 00:28
  • Good question. @IanB. It looks to me that Google Chrome is not using GTK for this, unless not a heavily tuned GTK. I will have a look inside gedit's source code and hopefully will figure it out. – Rafał Cieślak Sep 12 '12 at 11:27
  • According to gtkmm docs there is a class Gtk::Revealer which does exactly what u need. Honestly I've never used it and that's why I do not post an answer. Revealer inherits Gtk::Bin so it can store a single widget. Also there is enum which configures animation type like fade in, slide up ,left etc. More here https://developer.gnome.org/gtkmm/stable/group__gtkmmEnums.html#ga027016b2a3cb48c00420bd5c883d2542 – fnc12 Apr 06 '15 at 18:44
  • @fnc12 Yes, that was incubated in `libgd` and upstreamed to GTK+ in 2013, after this question and its answers; see [my new answer](https://askubuntu.com/a/960527/436580). – underscore_d Sep 29 '17 at 12:36

4 Answers4

8

I have achieved a fade-out effect using pure GTK and CSS.

It is only working in GTK 3.6 and I am not sure if a slide in / out effect would be possible, however, if you want, you can look at the source at launchpad.net/uberwriter

It works through a state-change and then GTK Transitions... Maybe with height // width that would be possible, too.

EDIT

Because people obviously downvote me, here is another, more detailed explanation:

This is the CSS I have used:

GtkLabel:insensitive {
    color: rgba(255,255,255,0);
    transition: 500ms ease-in-out;
}

If you use this as CSS (I hope I am allowed to reference an explanation from myself, how to that: http://wolfvollprecht.de/blog/gtk-python-and-css-are-an-awesome-combo/) then you can use Gtk.StateFlags to fade out the Label.

e.g.:

label.set_state_flags(Gtk.StateFlags.INSENSITIVE, True)

Then you get a transition to zero opacity.

However, as I have noticed, there are not many options to influence placement / width with CSS, so I guess it's limited to colors / opacity etc.

Enjoy.

PS: Note that this only works in Gtk 3.6, since Ubuntu 12.10

wolfv
  • 580
  • 3
  • 11
  • People probably downvoted because the question asked for a sliding animation, but you gave an opacity transition, which is totally different... so I don't know why so many other people _upvoted_. Anyway, nowadays there is `GtkRevealer`, which can do both; see [my answer](https://askubuntu.com/a/960527/436580). – underscore_d Sep 29 '17 at 12:30
3

Such animation is not achievable in pure GTK+. There are no mechanisms that would process it.

I have given a quick look on gedit's source code, it's clear that they process this animation on their own. I have not looked into details, for the code related to animations is quite expanded, but I have noted that they incorporate Cairo drawing features for the animated search widget. Most likely the widget is animated by moving its position frame by frame and redrawing it on a different place in the overlay that is used on a single text display area.

That seems to be the simplest solution. (gedit's code seems to be prepared for many animations sharing the same code base, thus it may be an overkill to use it's exact approach in a simple application.)

To reproduce this effect, you will need to:

  • Use a custom widget for the UI piece that you want to slide in/out.
  • Make it react on draw event and periodical timeouts (to redraw each frame of animation)
  • Create a transparent overlay over the rest of your widgets (or any area that has to appear as if it was below the sliding widget)
  • Draw the animated widget manually on such overlay.

I can't come up with any easier solution. However, considering the fact that gedit developers do know GTK+ as probably very little do, there may be no simpler trick to achieve such effect.

Rafał Cieślak
  • 20,204
  • 7
  • 56
  • 86
  • It seems your idea it's the "simplest". I thought it could be done with some CSS hacking, but reading Gedit's code seems to be more like hardcoded and prepared for more than a simple search box entry, as you say. So, I'll try making a custom widget and, first, move it around on certain events (at least if it is possible). Thanks for your suggestions. – Ángel Araya Sep 12 '12 at 18:29
2

You can use a combination between Gtk.fixed(),GObject.timeout_add and the function move, here is an example in python :

#!/usr/bin/python*
from gi.repository import Gtk, GObject

class TestWindow(Gtk.Window):
     def animateImage(self):
        GObject.timeout_add(150,self.slideImage)

     def slideImage(self):
        self.positionX += 50;
        if(self.positionX > 800):
          self.fixedWidget.move(self.logo,self.positionX,200)
          return True        
        else:
          return False 

     def __init__(self):
        Gtk.Window.__init__(self, title='Registration')

        self.positionX = 500
        self.fixedWidget = Gtk.Fixed()
        self.fixedWidget.set_size_request(1920,1080)
        self.fixedWidget.show()

        self.logo = Gtk.Image.new_from_file('picture.png')
        self.logo.show()
        self.fixedWidget.put(self.logo,self.positionX,200)

        self.button1 = Gtk.Button('Click me to slide image!')
        self.button1.show()
        self.button1.connect('clicked', self.animateImage)
        self.button1.set_size_request(75,30)
        self.fixedWidget.put(self.button1,750,750)
        self.add(self.fixedWidget)

testWindow = TestWindow()
testWindow.set_size_request(1920,1080)
testWindow.set_name('testWindow')
testWindow.show()

Gtk.main()
2

Nowadays, there is a real answer to this question. Since it was originally asked and answered, the code for revealing a widget from libgd - which I presume is what GEdit was using at that time - has been upstreamed into GTK+ as GtkRevealer:

https://developer.gnome.org/gtk3/stable/GtkRevealer.html

GtkRevealer supports various forms of transition, including the cardinal directions of slide and a fade on the opacity.

So, these days, it's as simple as adding the widget that you want to transition to a GtkRevealer and using its :transition-(type|duration) and :reveal-child properties.

underscore_d
  • 293
  • 3
  • 12
  • This is a useful answer but I think it may better for people to show how this could be done in python+GTK, ready-made. I have found many examples here to be incomplete and hard to reproduce, in particular after years passed, and no code has posted at all that has at the least once worked. – shevy Feb 12 '21 at 18:47