Re: How to extend a widget?
On 12/16/2011 08:16 AM, jacky wrote: As I said, I'm not sure this is the right way to do such a thing, so I would appreciate any help/information on how one would do this properly. Since GTK is object oriented, you could just create a new class that inherits from GtkCalender. However this is C we're using, so it's not quite as simple as in C++, Java, or Python. If I recall correctly, you'll end up with 3 files. 2 .C files and 1 .H One C file will contain the klass and vtable initialization stuff, one .C file of your implementation, and one .H file with your public interfaces, cast macros, and so forth. At one time GTK people were using a tool called gob to compile a single file of some object-oriented C-like syntax into these files. Seems to me, though, that you'd be well-served in doing this in Vala. Vala itself defines a C-like (more C#-like) language that compiles into C and GObject code. You can take the output of Vala and use it in your normal C development. In fact the job you describe is just what Vala was originally designed for, though Vala has gone far beyond just being a GObject compiler. Michael. ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: How to extend a widget?
On 12/16/2011 11:05 AM, Michael Torrie wrote: stuff As I think about it, my knowledge of extending GTK really is out of date. So I'm not at all sure how to do in C anymore. But Vala still just might be the ticket. Emitted Vala code is supped to be directly usable from a C program. I know the LXDE folk are now using Vala to work on and extend their old C code. You can ask on the Vala list for more informatin. ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: How to extend a widget?
Thanks. I will have a look into Vala, although for projects I have planned, I really want/need to be using C. And while GTK is oriented-object, it is written in C and, AFAIK, there are no such things as classes in C? I believe the way to create a widget based on/extending another one is how I have done so far (based on the docs /tutorials I read), only I'm not sure how to properly do things like overriding functions to change behaviors or add features. If Vala allows to do that easily and does produce C code though, I might try and see how it does/what code it produces, but I'm not sure learning a new language is something I wanna get into right now... -jacky On 12/16/2011 07:05 PM, Michael Torrie wrote: On 12/16/2011 08:16 AM, jacky wrote: As I said, I'm not sure this is the right way to do such a thing, so I would appreciate any help/information on how one would do this properly. Since GTK is object oriented, you could just create a new class that inherits from GtkCalender. However this is C we're using, so it's not quite as simple as in C++, Java, or Python. If I recall correctly, you'll end up with 3 files. 2 .C files and 1 .H One C file will contain the klass and vtable initialization stuff, one .C file of your implementation, and one .H file with your public interfaces, cast macros, and so forth. At one time GTK people were using a tool called gob to compile a single file of some object-oriented C-like syntax into these files. Seems to me, though, that you'd be well-served in doing this in Vala. Vala itself defines a C-like (more C#-like) language that compiles into C and GObject code. You can take the output of Vala and use it in your normal C development. In fact the job you describe is just what Vala was originally designed for, though Vala has gone far beyond just being a GObject compiler. Michael. ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: How to extend a widget?
jacky wrote: What I was looking into would be more taking an existing widget, and modifying it a little, as in changing its behavior on some aspect, or adding a feature, something like that. My question is: what would be the best/standard/recommanded way to do such a thing? Widgets are not plugins. They are whole objects. There is no extensible feature to them. You will have two choices: 1. Copy an entire GTK widget and give it a unique name. Example: GtkButton becomes GtkMyButton 2. Create a shell widget that uses existing GTK widgets inside of it to do what you want. In the event you need to touch the GTK widgets inside, you can make your new widget a simple struct and have pointers to the interior GTK widgets. I would suggest number 2, unless you are doing something very radical. ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: How to extend a widget?
Michael Cronenworth wrote: 2. Create a shell widget Rereading your post I think you called this composite widget. I'm not sure why you are opposed to this idea. I've created a composite widget myself and it has worked great for me. ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: How to extend a widget?
Right, thanks. Alright so using extend might not have been the right term (probably comes because I've done some PHP and have been influenced by that), sorry. Oh, and I've used the term composite widget simply because I read it here, and assumed it was how such widgets were called: http://developer.gnome.org/gtk-tutorial/stable/x2200.html Anyways, I don't have a problem with creating a new (shell/composite) widget using another one inside of it, it's actually exactly what I did in my example: created a widget JjkCalendar which contains a GtkCalendar. It's just that I felt (from tutorials and such I read) that such (composite) widgets were only using widgets they contain and combining them together, rather than modifying their behaviors. I guess my question is more: how do I affect this widget's internal behavior? how do I add a new feature (which might imply alter current way to draw the widget) ? That is, do something not really supported/planned by the widget's public API. Like I said, in the example code I posted, in order to do that, and alter GtkCalendar's behavior, I needed to redefine GtkCalendarPrivate in my widget, so that I could change values contained the GtkCalendar's private struct. Also had to copy/paste a few functions as well -- is that okay, or will it lead to problems? And if so, what's the right way to do it then? -jacky On 12/16/2011 11:03 PM, Michael Cronenworth wrote: jacky wrote: What I was looking into would be more taking an existing widget, and modifying it a little, as in changing its behavior on some aspect, or adding a feature, something like that. My question is: what would be the best/standard/recommanded way to do such a thing? Widgets are not plugins. They are whole objects. There is no extensible feature to them. You will have two choices: 1. Copy an entire GTK widget and give it a unique name. Example: GtkButton becomes GtkMyButton 2. Create a shell widget that uses existing GTK widgets inside of it to do what you want. In the event you need to touch the GTK widgets inside, you can make your new widget a simple struct and have pointers to the interior GTK widgets. I would suggest number 2, unless you are doing something very radical. ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: How to extend a widget?
jjacky wrote: Anyways, I don't have a problem with creating a new (shell/composite) widget using another one inside of it, it's actually exactly what I did in my example: created a widget JjkCalendar which contains a GtkCalendar. Your composite widget project is similar to mine. I created a custom widget that is a text input combo box that if you click on the drop down button it displays a GtkCalendar. You can type in the date (in any format) and it will select the date in the GtkCalendar widget. It's just that I felt (from tutorials and such I read) that such (composite) widgets were only using widgets they contain and combining them together, rather than modifying their behaviors. You can certainly modify their behaviors. I catch and call signals that you normally wouldn't in order to parse and display the correct date format and positioning of the GtkCalendar widget. I guess my question is more: how do I affect this widget's internal behavior? how do I add a new feature (which might imply alter current way to draw the widget) ? That is, do something not really supported/planned by the widget's public API. If signal catching/calling are not enough then you might be best off creating a brand new widget. It seems you want to change the drawing of the GtkCalendar widget so you are on the right track of creating your own widget. Like I said, in the example code I posted, in order to do that, and alter GtkCalendar's behavior, I needed to redefine GtkCalendarPrivate in my widget, so that I could change values contained the GtkCalendar's private struct. Also had to copy/paste a few functions as well -- is that okay, or will it lead to problems? And if so, what's the right way to do it then? I'll admit I hadn't looked at your example the first go around. If you wish to customize the positioning, coloring, and text of each day then you must create your own widget. However, if all you want is to color the current day, then I think there already exist ways to do this without having to create a whole new widget. First, you have to set the day, and second you can theme it as you are trying to do already. Setting the day alone will color the current day. Is that all you want? In regards to your second question: As long as you are not modifying your system's GTK libraries you will not have problems in the future. ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: How to extend a widget?
On 12/16/2011 02:52 PM, jjacky wrote: Thanks. I will have a look into Vala, although for projects I have planned, I really want/need to be using C. Precisely. Vala makes the C Gobjects. You could use Vala to construct a class with a bunch of empty methods and then use the generated C code and fill in your code, abandoning the vala as a scaffold. And while GTK is oriented-object, it is written in C and, AFAIK, there are no such things as classes in C? Classes and other Object-oriented things are merely syntactic sugar in any language. GTK is certainly object-oriented through and through with all the classic aspects of Polymorphism, inheritance, and encapsulation. I believe the way to create a widget based on/extending another one is how I have done so far (based on the docs /tutorials I read), only I'm not sure how to properly do things like overriding functions to change behaviors or add features. Overriding methods is done through the GOBject's vtable. Virtual methods (as in C++) are dispatched through a function table. In the raw C code of GTK objects, this is a special struct. At least the way it used to work in GTK (my knowledge is a bit rusty) was that one struct contained the object's data, and this other stuct (sometimes called a 'klass' struct), contained the vtable. Any call to a virtual method would, using the object struct pointer itself, look up the klass structure, and look up the method to call (classic polymorphism). If Vala allows to do that easily and does produce C code though, I might try and see how it does/what code it produces, but I'm not sure learning a new language is something I wanna get into right now... Sure. as I said in my e-mail GTK developers used to use a tool called gob to create GObject-based classes, but that also has a pseudo-language. That said, working with GOBjects in C requires a lot of boilerplate code (to implement the object-orientedness), so using Vala or GOB (whatever the latest incarnation is), seems like a good idea to me, specially if you want to make your own classes and inherit, etc. ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: How to extend a widget?
On 12/16/2011 03:03 PM, Michael Cronenworth wrote: jacky wrote: What I was looking into would be more taking an existing widget, and modifying it a little, as in changing its behavior on some aspect, or adding a feature, something like that. My question is: what would be the best/standard/recommanded way to do such a thing? Widgets are not plugins. They are whole objects. There is no extensible feature to them. Not true. You can inherit from like you would any other class. And override virtual methods, add you own. If this were not possible GTK would have been abandoned as a serious platform long ago. You will have two choices: 1. Copy an entire GTK widget and give it a unique name. Example: GtkButton becomes GtkMyButton You really could Create a GtkMyButton by inheriting from GtkButton and adding your own code. However, just as in C++, the ability to override specific methods depends on whether they were made as virtual or static methods. static methods can't be overridden, but you could just shadow them with your own methods and use them instead. ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: How to extend a widget?
On 12/16/2011 03:03 PM, Michael Cronenworth wrote: Widgets are not plugins. They are whole objects. There is no extensible feature to them. Just for your information, here's a couple of examples of extending GtkButton using inheritance and the GObject Builder tool: http://www.jirka.org/gtk-button-count.gob.html http://www.jirka.org/my-person.gob.html Converting the gob code to C and you should see how to do it in straight C. ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: How to extend a widget?
On 12/16/2011 02:52 PM, jjacky wrote: And while GTK is oriented-object, it is written in C and, AFAIK, there are no such things as classes in C? As always, read the docs. Here is the documentation describing how to create new GObjects, and inherit from existing ones, implement virtual methods, etc. So if you find that you really do need to make your own subclass of the GtkCalendar you can easily do it, though as the other poster talks about, a composite widget might be the ticket too. Just remember how relationships in OOP work: The is a relationship means inheritance. the has a relationship means composite widgets. If your widget simply has a calender, then the composite widget is the way to go. If it actually is a calendar, albeit a special one, inheritance is the way to go. http://developer.gnome.org/gobject/stable/ The GOB thing I was referring to earlier: http://www.jirka.org/gob.html a specific example of using gob to extend GtkButton: http://www.jirka.org/gtk-button-count.gob.html The GOB examples you should be able to compile to straight C and use that boilerplate to implement your own pure-C extension of GtkCalendar. ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: How to extend a widget?
On Fri, Dec 16, 2011 at 04:09:54PM -0700, Michael Torrie wrote: 1. Copy an entire GTK widget and give it a unique name. Example: GtkButton becomes GtkMyButton You really could Create a GtkMyButton by inheriting from GtkButton and adding your own code. However, just as in C++, the ability to override specific methods depends on whether they were made as virtual or static methods. static methods can't be overridden, but you could just shadow them with your own methods and use them instead. I wish it was so. What invariably happens in practice is this: (a) You find that the widget implementation either provides some library-level-private _gtk_button_foo() methods or depends on such methods. This is the absolutely worst case because it can easily prevent even copying the code and creating a similarly behaving widget if it needs to use these functions. Unfortunately quite common. (b) Other code in Gtk+ calls the static methods. This means that you cannot substitute your derived widget for the base class if you need different behaviour (but you can happily use the derived widget in your own code). Apparently quite rare, possibly because the devs usually convert this to (a) by making the static method library-private. (c) To extend the virtual methods you would need to access parent widget state which is private. So you need to copy the implementation. If you do not run in to (a) or (b) then consider yourself lucky. Note I do not talk about trivial extensions such as those you posted. Could you write GtkToggleButton derived from GtkButton if it did not exist? Nope. Yeti ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: How to extend a widget?
Thanks, I do need to do some more reading on the gobject docs, great stuff there. What I'm looking for is inheritance, and I see how it could be done yes. However, that would require the original widget to be done using virtual public methods, and I'm afraid this isn't the case unfortunately... -j On 12/17/2011 12:21 AM, Michael Torrie wrote: On 12/16/2011 02:52 PM, jjacky wrote: And while GTK is oriented-object, it is written in C and, AFAIK, there are no such things as classes in C? As always, read the docs. Here is the documentation describing how to create new GObjects, and inherit from existing ones, implement virtual methods, etc. So if you find that you really do need to make your own subclass of the GtkCalendar you can easily do it, though as the other poster talks about, a composite widget might be the ticket too. Just remember how relationships in OOP work: The is a relationship means inheritance. the has a relationship means composite widgets. If your widget simply has a calender, then the composite widget is the way to go. If it actually is a calendar, albeit a special one, inheritance is the way to go. http://developer.gnome.org/gobject/stable/ The GOB thing I was referring to earlier: http://www.jirka.org/gob.html a specific example of using gob to extend GtkButton: http://www.jirka.org/gtk-button-count.gob.html The GOB examples you should be able to compile to straight C and use that boilerplate to implement your own pure-C extension of GtkCalendar. ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: How to extend a widget?
Alright, I think I'm starting to see things a little better now - thank you all. I believe, in the case of GtkCalendar, there are no virtual public methods, only static/private ones, and most of them use other such methods as well as the private structure, which is why creating a widget extending it isn't all that possible. Therefore, I think I would need to write a new widget from scratch, so based on GtkWidget and not GtkCalendar, and basically copy/paste the code from GtkCalendar into my own calendar, then applying whatever changes I want. (And I'm thinking accessing the private structure the way I did in my example is just a bad idea, which will lead to troubles as soon as the private struct changes...?) So I guess I'm gonna have to go ahead and write my own calendar widget, but inheriting from GtkWidget this time. Also means it won't be castable as GtkCalendar, but I guess that's due to how it was implemented, which unfortunately doesn't allow for it. -jacky On 12/17/2011 12:47 AM, David Nečas wrote: On Fri, Dec 16, 2011 at 04:09:54PM -0700, Michael Torrie wrote: 1. Copy an entire GTK widget and give it a unique name. Example: GtkButton becomes GtkMyButton You really could Create a GtkMyButton by inheriting from GtkButton and adding your own code. However, just as in C++, the ability to override specific methods depends on whether they were made as virtual or static methods. static methods can't be overridden, but you could just shadow them with your own methods and use them instead. I wish it was so. What invariably happens in practice is this: (a) You find that the widget implementation either provides some library-level-private _gtk_button_foo() methods or depends on such methods. This is the absolutely worst case because it can easily prevent even copying the code and creating a similarly behaving widget if it needs to use these functions. Unfortunately quite common. (b) Other code in Gtk+ calls the static methods. This means that you cannot substitute your derived widget for the base class if you need different behaviour (but you can happily use the derived widget in your own code). Apparently quite rare, possibly because the devs usually convert this to (a) by making the static method library-private. (c) To extend the virtual methods you would need to access parent widget state which is private. So you need to copy the implementation. If you do not run in to (a) or (b) then consider yourself lucky. Note I do not talk about trivial extensions such as those you posted. Could you write GtkToggleButton derived from GtkButton if it did not exist? Nope. Yeti ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: How to extend a widget?
On 12/16/2011 05:24 PM, jjacky wrote: Thanks, I do need to do some more reading on the gobject docs, great stuff there. What I'm looking for is inheritance, and I see how it could be done yes. However, that would require the original widget to be done using virtual public methods, and I'm afraid this isn't the case unfortunately... Hmm, yes. That's what I read in Mr. Nečas's post. Unfortunate. Though as he said if only you are going to be using this new widget you can just make new static methods and use them instead. Polymorphism only comes into play when you want to call the base class method on your derived class. In other words unless you're interacting with existing code (binary or source) that is expecting the GtkCalendar class objects, you can call gtk_mycalendar_*() methods instead of gtk_calendar_*() methods. ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list