Thread: Gdk-pixbuf and file locations (and other GTK+ questions)

  1. #1
    Registered User
    Join Date
    May 2015
    Posts
    52

    Gdk-pixbuf and file locations (and other GTK+ questions)

    Hello everyone!
    As one or two of you may remember, I was trying to learn GTK+ a while ago, so as to develop a text-based game. I gave it up for a while due to my finals, but I'm back on it now and have a question.
    Or rather a collection of such.

    First off, I want to try assigning a background image to a window. For that, I'd need the image location in utf-8 format (the "GLib file name encoding") to pass it through gdk_pixbuf_new_from_file(), unless I'm mistaken. I found some basics on how to convert to and from utf-8, but most were for C# or C++, and I'm looking for a clear answer, should you be able to provide one.

    Secondly, while I haven't tried it yet, I assume that the image won't be able to surpass the borders of the window. Could the image's edges be transparent? Will that work through pixbuf? Also, could I somehow bypass showing the border of the window (including the "minimize" and "close" buttons)?

    Lastly, if I want to rig up sounds to work with some events in GTK+, do you have a recommended library to work with?


    I understand that it's a lot of questions, but I'm only asking because the documentation on the subject (and the second edition of GTK+, since I could not make the third one work) is lacking.
    I appreciate any and all help :3

  2. #2
    Registered User migf1's Avatar
    Join Date
    May 2013
    Location
    Athens, Greece
    Posts
    385
    Quote Originally Posted by Sotos View Post
    Hello everyone!
    ...

    First off, I want to try assigning a background image to a window. For that, I'd need the image location in utf-8 format (the "GLib file name encoding") to pass it through gdk_pixbuf_new_from_file(), unless I'm mistaken. I found some basics on how to convert to and from utf-8, but most were for C# or C++, and I'm looking for a clear answer, should you be able to provide one.
    I'm not sure that you need the filename in utf8 encoding for gdk_pixbuf_new_from_file(), but even if you do, it is much easier to pass -fexec-charset=utf-8 to the command-line of gcc (perhaps coupled with -finput-charset=XXX where XXX is the encoding of your source files, in libiconv's "terminology").

    Now for the real juice (setting a bg-image to a Gtk+2 window), here's a couple of links on how you may do it:

    1. c - How does one set the background of a GtkWindow to an image? - Stack Overflow
    Note: (an irrelevant note to your question) In the code presented at the above link, add g_signal_connect( window, "destroy", G_CALLBACK(gtk_main_quit), NULL ); somewhere between creating the window and calling the gtk main loop.

    2. View topic - How to load a background image in a window.
    Here's a bit more generalized form of the function shown at the above link (could be further improved):

    Code:
    #include <gtk/gtk.h>
    
    /*********************************************//**
     *
     *************************************************
     */
    GtkWidget *SetupWindow(
        const gchar *title,    /* title of the window */
        const gchar *bgfname,  /* filename of image to be used as background */
        gboolean Transient,    /* should the windows be transient? */
        GtkWindow *parent      /* parent window for transient */
        )
    {
        GdkPixmap *background = NULL;
        GdkPixbuf *pixbuf = NULL;
        GtkStyle  *style = NULL;
        GError    *error = NULL;
        GtkWidget *window = NULL;
    
        pixbuf = gdk_pixbuf_new_from_file( bgfname, &error );
        if ( NULL != error ) {
            if ( GDK_PIXBUF_ERROR == error->domain ) {
                g_print( "Pixbuf Related Error:\n" );
            }
            if ( G_FILE_ERROR == error->domain ) {
                g_print( "File Error: Check file permissions and state:\n" );
            }
    
            g_printerr ("%s\n", error[0].message );
            return NULL;
        }
        gdk_pixbuf_render_pixmap_and_mask( pixbuf, &background, NULL, 0 );
    
        style = gtk_style_new();
        style->bg_pixmap[0] = background;
    
        window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
        gtk_window_set_title( GTK_WINDOW (window), title );
        // gtk_window_maximize( GTK_WINDOW(window) );
        gtk_window_set_modal( GTK_WINDOW(window), TRUE );
        gtk_window_set_default_size( GTK_WINDOW(window), 640, 480 );
        gtk_widget_set_style( GTK_WIDGET(window), GTK_STYLE(style) );
        gtk_window_set_position( GTK_WINDOW(window), GTK_WIN_POS_CENTER_ALWAYS );
    
        gtk_container_set_border_width( GTK_CONTAINER(window), 14 );
    
        if ( Transient ) {
            gtk_window_set_transient_for( GTK_WINDOW(window), parent );
        }
    
    //    gtk_widget_show( window );
        return(window);
    }
    
    /*********************************************//**
     *
     *************************************************
     */
    int main( int argc, char *argv[] )
    {
        GtkWidget *w = NULL;
    
        gtk_init( &argc, &argv );
        w = SetupWindow( "Tile", "appicon1_128.png", TRUE, NULL );
        g_signal_connect( w, "destroy", G_CALLBACK(gtk_main_quit), NULL );
    
        gtk_widget_show_all( w );
        gtk_main();
    
        return 0;
    }

    Secondly, while I haven't tried it yet, I assume that the image won't be able to surpass the borders of the window. Could the image's edges be transparent? Will that work through pixbuf? Also, could I somehow bypass showing the border of the window (including the "minimize" and "close" buttons)?
    You can use gtk_window_set_decorated() after you have created your window (and before displaying it). Note however that it depends on the windows-manager of your OS whether it will honor the request or not.

    Lastly, if I want to rig up sounds to work with some events in GTK+, do you have a recommended library to work with?
    ...
    I don't have 1st-hand experience with a stand-alone sound library, so I can't really recommend, but if you are looking for a more spherical frameworks (instead of GUI ones) you may want to have a look at SDL2, Allegro5 or SFML (the latter is mainly for C++ but among others it also offers c-bindings, called csfml I think).
    "Talk is cheap, show me the code" - Linus Torvalds

  3. #3
    Registered User
    Join Date
    May 2015
    Posts
    52
    Oh, you're awesome. Thanks a lot

    I managed to get gtk_window_set_decorated() to work quite easily, and it has no issues in Windows, which is great.
    About the sound libraries, I'll take a look on them later.

    On the window background question, I located the exact stackoverflow.com entry you posted, so I was working off that ^_^
    In the entry for gdk_pixbuf_new_from_file() in the link you shared, it says that the "filename" variable is in the Glib file name encoding, which, after a quick google search, proved to be utf8.
    Now, I maaaaay not have gone around to compiling from the command line yet...
    Any other way I could get around to it? I mean, this time I really have no idea what to do.
    Say I have the file C:\Users\whatever\Desktop\test.png
    Could you walk me through the proccess to get the file name in the format I need for pixbuf?
    Last edited by Sotos; 06-24-2015 at 12:30 AM.

  4. #4
    Registered User migf1's Avatar
    Join Date
    May 2013
    Location
    Athens, Greece
    Posts
    385
    Quote Originally Posted by Sotos View Post
    Oh, you're awesome. Thanks a lot

    I managed to get gtk_window_set_decorated() to work quite easily, and it has no issues in Windows, which is great.
    About the sound libraries, I'll take a look on them later.
    Nice

    On the window background question, I located the exact stackoverflow.com entry you posted, so I was working off that ^_^
    In the entry for gdk_pixbuf_new_from_file() in the link you shared, it says that the "filename" variable is in the Glib file name encoding, which, after a quick google search, proved to be utf8.
    Now, I maaaaay not have gone around to compiling from the command line yet...
    Any other way I could get around to it? I mean, this time I really have no idea what to do.
    Say I have the file C:\Users\whatever\Desktop\test.png
    Could you walk me through the proccess to get the file name in the format I need for pixbuf?
    Hey man, you really should spend some time to get familiar with the command-line. It's not that hard

    Anyway, if I recall correctly, you are using the latest Code::Blocks on Windows, which comes with the TDM GCC tool-chain.

    Although I personally use either the mingw or the mingw-w64 tool-chains, I see no reason why TDM's would have a problem with the gcc's -finput-charset/-fexec-charset command-line options.

    Ok, first you should set the encoding of your source files. With C::B you can do it via the menu Edit->File encoding... see the picture: http://i.imgur.com/ENiOurD.png?1

    Setting it to UTF-8 should suffice, if you do NOT want to print messages in the console (if you want to print messages to the Window's console, try setting it to System default instead, but if it doesn't work then things can get complicated and C::B may not be the right tool... personally I use Notepad++ which is much more flexible than C::B in viewing/setting/changing the encoding of the source files).

    Next you should specify gcc's -finput-charset/-fexec-charset command-line options. After you have created your project in C::B, use the menu Project -> Build options ... see this picture: http://i.imgur.com/nUXq9uQ.png?1

    First notice that in the tree-pane on the left, what is selected is the ROOT of the tree (called hello in the picture). This makes sure that the changes you do will affect BOTH the Debug and the Release builds of your project.

    Then type-in the -finput-charset/-fexec-charset command-options to the location shown in the picture, but CONTRARY to what the picture shows, set them BOTH to utf-8 (actually, gcc is supposed to default to utf-8 if those options are not specified, but I'm not sure if that's the case in all Windows' ports... so better to specify them both).

    Assuming you have set you source encoding to UTF-8 you should now be good to go

    Regarding the background-image, the following should be a more general function for the task:

    Code:
    /*********************************************//**
     * 
     *************************************************
     */
    GtkWidget *mygtk2_wind_get_parent_window( GtkWidget *wind )
    {
        GtkWidget *parent = NULL;
    
        if ( NULL == wind ) {
            return NULL;
        }
    
        parent = gtk_widget_get_toplevel( wind );
        if ( !gtk_widget_is_toplevel(parent) ) {
            return NULL;
        }
    
        return parent;
    }
    
    /*********************************************//**
     * 
     *************************************************
     */
    gboolean mygtk2_wind_set_bgimage_from_file(
        GtkWidget   *wind,    /* the window to host the background image */
        const gchar *bgfname  /* filename of image to be used as bgpixmap */
        )
    {
    //    GtkWidget *parent = NULL;      /* wind's parent window */
        GdkPixbuf *bgpixbuf = NULL;    /* pixbuf to load from file */
        GdkPixmap *bgpixmap = NULL;    /* pixmap to be created from pixbuf */
        GtkStyle  *style = NULL;
        GError    *error = NULL;
    
        /* sanity check */
        if ( NULL == wind || NULL == bgfname ) {
            return FALSE;
        }
    
        /* load image from file to bgpixbuf */
        bgpixbuf = gdk_pixbuf_new_from_file( bgfname, &error );
        if ( error ) {
            if ( GDK_PIXBUF_ERROR == error->domain ) {
                g_print( "Pixbuf Related Error:\n" );
            }
            if ( G_FILE_ERROR == error->domain ) {
                g_print( "File Error: Check file permissions and state:\n" );
            }
    
            g_printerr ("%s\n", error[0].message );
            return FALSE;
        }
    
        /*
         * Get bgpixmap pixmap from bgpixbuf, apply it to a new gtk_style
         * and finally apply the new style to the window.
         */
        gdk_pixbuf_render_pixmap_and_mask( bgpixbuf, &bgpixmap, NULL, 0 );
        style = gtk_style_new();
        style->bg_pixmap[0] = bgpixmap;
        gtk_widget_set_style( GTK_WIDGET(wind), GTK_STYLE(style) );
    
    #if 0
        /* NOTE: make wind transient for its parent window 
           DO WE REALLY NEED THIS? */
        parent = wind_get_parent_window( wind );
        if ( parent != wind ) {
            gtk_window_set_transient_for(
                GTK_WINDOW(wind),
                GTK_WINDOW(parent)
                );
        }
    #endif
    
        return TRUE;
    }
    The reason I have commented out the part that sets the window transient for its parent-window is that I'm not sure it is really needed when setting the background. Even if it is (which I believe it is NOT), it is probably a better idea to either pass the parent as a parameter to the function mygtk2_wind_set_bgimage_from_file() or do it separetely before or after calling the bgimage function (usually this is done when we setup our window).

    Anyway, I left the code in there (along with the function mygtk2_wind_get_parent_window()) just for reference. Again, I don't think it is needed, but I'm not 100% sure.

    PS1. I have a mygtk2.c file somewhere, with some simple mygtk2 utility functions I've made in the past. I'll look for it later on and when I find it I'll post it (I think it's small enough).

    PS2. How do I delete a attachment from my post? I put one of the pictures in this post as an attachment, but then I opted for a direct link. I don't seem to find how to delete the attachment though (it shows up when I'm previewing my post).
    "Talk is cheap, show me the code" - Linus Torvalds

  5. #5
    Registered User
    Join Date
    May 2015
    Posts
    52
    Well, you've helped me a lot so far, I'll take your word and try to get a bit familiar with the command line before I move any further.

    I managed to get basic compiling down, but I have a question. Do I have to set my current directory to a different folder every time (Code::Blocks gives each .c file its own folder, and tbh it's better like this, more organized) or is there a shortcut to do that for me?

    EDIT: Aaaagh, I copied and pasted the code on your first post to try stuff out, and I get undefined references to the pixbuf functions ;_;
    Last edited by Sotos; 06-26-2015 at 05:47 AM.

  6. #6
    Registered User migf1's Avatar
    Join Date
    May 2013
    Location
    Athens, Greece
    Posts
    385
    Quote Originally Posted by Sotos View Post
    Well, you've helped me a lot so far, I'll take your word and try to get a bit familiar with the command line before I move any further.
    The main reason I suggested to get familiar with the command-line options of your compiler (or even better its tool-chain), is because this way you will learn what is actually done every time you hit that "Build & Run" button in your IDE (or any IDE).

    IDEs actually construct and issue the command-line options according to the settings you have enabled/disabled in your project. All is jolly good, until you either be forced to change IDE (thus needing to learn a different UI), or until you need to issue commands that are not directly support by your IDE.

    Decent IDEs provide the ability to issue any extra command-line options by hand, which is essentially the same thing as typing them directly in the command-line.

    All in all, all IDEs (regardless their peculiarities and degree of UI friendliness, flexibility, etc) construct & issue the very same command-line. By knowing exactly how it is constructed and exactly how it will look like if it was given manually, gives you at the very least the ability to get full advantage of your IDE, or do it manually if your IDE lacks support for what you are trying to accomplish.

    In this post I've tried to explain to you the basics for compiling from the command-line, using the gcc driver tool. If you haven't done it already, please have a look at it.

    You don't have to use the command-line every time. I'm NOT suggesting to ditch your IDE in favor of the command-line. I'm just saying to get familiar with the command line first, so you can take full advantage of any IDE if you choose so.

    I managed to get basic compiling down, but I have a question. Do I have to set my current directory to a different folder every time (Code::Blocks gives each .c file its own folder, and tbh it's better like this, more organized) or is there a shortcut to do that for me?
    I'm not sure what you mean. When using the command-line, you issue the "cd" command to go into the folder containing the source code. Once in there, you type your compiler's command-line. If you don't specify explicitly a desired name for the produced executable (via the "-o name.exe" option), gcc will name it a.exe

    The folder containing the binary tools of your compiler (that is, the gcc.exe tool in our example) MUST be in the environment-variable called PATH (google how to add it manually for your OS... e.g. google "windows 8.1 how to set environment variable PATH" or something similar)

    EDIT: Aaaagh, I copied and pasted the code on your first post to try stuff out, and I get undefined references to the pixbuf functions ;_;
    Most probably you haven't linked against the libgdk_pixbuf-2.0.dll.a library.

    Ok, I'll try to guide you one more time on how to install gtk2 manually on Windows. I've already given you a link, in this post where again I'm trying to explain the same thing, for a gtk2 app I made a while ago, but it says other things too. So, here is only what you need:


    1. Download the latest 32bit GTK+2 binaries from the official site (either click on the 1st of my links here, or go to the official site and get the "all-in-bundle" for GTK+2.x). Do NOT download the 64bit version (it is officially marked as buggy).

    2. Unzip it anywhere you like, but make sure that the path does NOT contain spaces. Good candidate folder names would be something like: C:\libs\gtk2 or C:\gtk2 (let's go with the latter in this example).

    3. Add C:\gtk2\bin; into the PATH environment-variable of Windows (so your programs can link dynamically to GTK+2 without needing to copy any .dll files to the folder of your executables).

    That's it!

    That was easy. The tedious part is the compilation, due to GTK's so many dependencies. You need to pass to gcc's driver a hell lot of -I, -L and -l command-line options.

    To be exact, to compile a gtk2_hello.c you need to issue the following command-line:

    Code:
    gcc gtk2_hello.c -o gtk2_hello.exe -std=c99 -Wall -Wextra -fexec-charset=utf-8 -mms-bitfields -Ic:/gtk2/include/gtk-2.0 -Ic:/gtk2/lib/gtk-2.0/include -Ic:/gtk2/include/atk-1.0 -Ic:/gtk2/include/gdk-pixbuf-2.0 -Ic:/gtk2/include/cairo -Ic:/gtk2/include/pango-1.0 -Ic:/gtk2/include/glib-2.0 -Ic:/gtk2/lib/glib-2.0/include -Ic:/gtk2/include -Ic:/gtk2/include/freetype2 -Ic:/gtk2/include/libpng14 -Lc:/gtk2/lib -lgtk-win32-2.0 -lgdk-win32-2.0 -latk-1.0 -lgio-2.0 -lgdk_pixbuf-2.0 -lpangowin32-1.0 -lgdi32 -lpangocairo-1.0 -lpango-1.0 -lcairo -lgobject-2.0 -lgmodule-2.0 -lgthread-2.0 -lglib-2.0 -lintl
    You may greatly simplify the above mess, by creating a environment-variable, say GTK2_GCC_OPTIONS, containing all the GTK2 fat...
    -mms-bitfields -Ic:/gtk2/include/gtk-2.0 -Ic:/gtk2/lib/gtk-2.0/include -Ic:/gtk2/include/atk-1.0 -Ic:/gtk2/include/gdk-pixbuf-2.0 -Ic:/gtk2/include/cairo -Ic:/gtk2/include/pango-1.0 -Ic:/gtk2/include/glib-2.0 -Ic:/gtk2/lib/glib-2.0/include -Ic:/gtk2/include -Ic:/gtk2/include/freetype2 -Ic:/gtk2/include/libpng14 -Lc:/gtk2/lib -lgtk-win32-2.0 -lgdk-win32-2.0 -latk-1.0 -lgio-2.0 -lgdk_pixbuf-2.0 -lpangowin32-1.0 -lgdi32 -lpangocairo-1.0 -lpango-1.0 -lcairo -lgobject-2.0 -lgmodule-2.0 -lgthread-2.0 -lglib-2.0 -lintl
    Now you can compile by issuing just...
    Code:
    gcc gtk2_hello.c -o gtk2_hello.exe -std=c99 -Wall -Wextra -fexec-charset=utf-8  %GTK2_GCC_OPTIONS%
    If instead of the standard console of Windows (cmd.exe) you use msys which comes with most (if not all) mingw toolchains (make sure the PATH environment variable contains both C:\mingw\msys\1.0\bin and C:\mingw\msys\1.0\bin - adjust according to where mingw is installed), then you can also simplify greatly the compilation, without using a dedicated environment-variable, by issuing the following command:
    Code:
    gcc gtk2_hello.c -o gtk2_hello.exe -std=c99 -Wall -Wextra -fexec-charset=utf-8 `pkg-config --cflags --libs gtk+-2.0`
    For details on the latter, read this. It's for Linux, but it's the same on Windows via the msys console (the only difference is that you may need to put the pkg-config stuff at the end of the command-line... do it anyway).

    Note that, you also need to have the full path of gcc.exe (and the other compiler tools) into the PATH environment-variable of Windows.

    I'm using the plain mingw toolchain installed in C:\mingw and the compiler tools are located in the folder C:\mingw\bin

    You are using the tdm-gcc toolchain, via the installation of Code::Blocks, so search for gcc.exe in your hard-disk and add the full-path of its folder into the PATH environment-variable of Windows (unless it's already there, obviously). Just to be sure, besides gcc.exe this folder contains a lot more executables, like g++.exe, gdb.exe, gettext.exe, etc


    For completeness, and in case you or are anyone else needs to setup any decent IDE's project for GTK2, with any compiler, here is the list of GTK2 dependencies (assuming that GTK2 is installed in the folder: c:\gtk2... otherwise adjust accordingly):

    Header Paths

    Code:
     c:\gtk2\include\gtk-2.0
     c:\gtk2\lib\gtk-2.0\include
     c:\gtk2\include\atk-1.0
     c:\gtk2\include\gdk-pixbuf-2.0
     c:\gtk2\include\cairo
     c:\gtk2\include\pango-1.0
     c:\gtk2\include\glib-2.0
     c:\gtk2\lib\glib-2.0\include
     c:\gtk2\include
     c:\gtk2\include\freetype2
     c:\gtk2\include\libpng14
    Libraries' Paths

    Code:
    c:/gtk2/lib
    Libraries

    Code:
     gtk-win32-2.0.lib
     gdk-win32-2.0.lib
     atk-1.0.lib
     gio-2.0.lib
     gdk_pixbuf-2.0.lib
     pangowin32-1.0.lib
     gdi32.lib
     pangocairo-1.0.lib
     pango-1.0.lib
     cairo.lib
     gobject-2.0.lib
     gmodule-2.0.lib
     gthread-2.0.lib
     glib-2.0.lib
     intl.lib
    Last edited by migf1; 06-27-2015 at 03:24 AM.
    "Talk is cheap, show me the code" - Linus Torvalds

  7. #7
    Registered User
    Join Date
    May 2015
    Posts
    52
    I get the same error a lot of times when trying to compile, though everything should be set up correctly.
    It says, for every library and header,
    "Skipping incompatible C:/GTK/lib/libwhatever.dll.a when searching for -lwhatever
    Skipping incompatible C:/GTK/lib/whatever.lib when searching for -lwhatever"
    Where obviously "whatever" is the name of every library and header.

    I'll try to work this out, though any advice would be appreciated.

    Meanwhile, shouldn't my IDE automatically link against pixbuf and all the other libraries as well, since I'm running a GTK+ project?

  8. #8
    Registered User migf1's Avatar
    Join Date
    May 2013
    Location
    Athens, Greece
    Posts
    385
    Quote Originally Posted by Sotos View Post
    I get the same error a lot of times when trying to compile, though everything should be set up correctly.
    It says, for every library and header,
    "Skipping incompatible C:/GTK/lib/libwhatever.dll.a when searching for -lwhatever
    Skipping incompatible C:/GTK/lib/whatever.lib when searching for -lwhatever"
    Where obviously "whatever" is the name of every library and header.

    I'll try to work this out, though any advice would be appreciated.
    I'm afraid these errors indicate incompatibility between your compiler (tdm gcc) and the pre-compiled GTK2 binaries.

    Actually, the official GTK site, in the Downloads page for Windows (paragraph "What toolchain to use"), states that the 32-bit precompiled binaries have been made with the MinGW toolchain (and their 64-bit counterparts have been made with the Mingw-w64 toolchain).

    Unfortunately, this means that the tdm-gcc compiler that gets installed with Code::Blocks is useless with the distributed binaries of GTK+2.

    You should either compile the GTK+2 binaries form its sources using tdm-gcc, or install the MinGW toolchain and use that when compiling GTK2 applications. IMO, the latter is probably a better option in your case.

    If you decide to give it a try, most probably you will also want to replace tdm-gcc with mingw inside Code::Blocks ( Settings -> Compiler -> <Global compiler settings> | [Toolchain executables] ).

    Meanwhile, shouldn't my IDE automatically link against pixbuf and all the other libraries as well, since I'm running a GTK+ project?
    Yes it should. However if my memory serves me well, the default GTK+2 project template in Code::Blocks is missing the header/library directories & the linker option for gdk_pixbuf. You can add them in the project template, but I don't remember by heart how to do it. Try googling it.

    Also, don't forget that you can always open en EMPTY project and simply set it up manually for GTK2. All the required info to so is available in my previous post.

    Finally, you can always test things first directly in the command line.
    "Talk is cheap, show me the code" - Linus Torvalds

  9. #9
    Registered User migf1's Avatar
    Join Date
    May 2013
    Location
    Athens, Greece
    Posts
    385
    Got some free time, so here is a way to setup manually an Empty Code::Blocks project for GTK2 applications (assuming GTK2 is already installed in: C:\unix\libs\gtk2).

    1. Create an empty project via File -> New project... (give it a name and keep other settings to default values).

    2. Open the build-options for your project, via Project -> Build options...

    3. First select the root of the tree in the tree-pane on the left (it is called: gtk2_hello in the pictures that follow), then set the Compiler settings [ Other options] and finally set the Linker settings [Other linker options], as shown in the following pictures:

    Compiler settings [Other settings]
    (I'm also listing them in code-tags so you can copy & paste them):
    Code:
    -std=c99 -mms-bitfields -IC:/unix/libs/gtk2/include/gtk-2.0 -IC:/unix/libs/gtk2/lib/gtk-2.0/include -IC:/unix/libs/gtk2/include/atk-1.0 -IC:/unix/libs/gtk2/include/cairo -IC:/unix/libs/gtk2/include/gdk-pixbuf-2.0 -IC:/unix/libs/gtk2/include/pango-1.0 -IC:/unix/libs/gtk2/include/glib-2.0 -IC:/unix/libs/gtk2/lib/glib-2.0/include -IC:/unix/libs/gtk2/include -IC:/unix/libs/gtk2/include/freetype2 -IC:/unix/libs/gtk2/include/libpng14
    Linker settings [Other linker options]
    (I'm also listing them in code-tags so you can copy & paste them):
    Code:
    -LC:/unix/libs/gtk2/lib -lgtk-win32-2.0 -lgdk-win32-2.0 -latk-1.0 -lgio-2.0 -lpangowin32-1.0 -lgdi32 -lpangocairo-1.0 -lgdk_pixbuf-2.0 -lpango-1.0 -lcairo -lgobject-2.0 -lgmodule-2.0 -lgthread-2.0 -lglib-2.0 -lintl
    You are done with GTK2.

    Now for setting up C::B to use the mingw tool-chain (instead of the tdm-gcc one), and assuming it is already installed in: C:\unix\mingw, do it via the menu Settings -> Compiler <Global compiler settings (on the left-pane)>[Toolchain executables...], as shown in
    this picture.

    You should be good to go now.

    PS. If you plan to also use directly the command-line, make sure that the installer of the TDM-GCC toolchain has NOT add its own folders into your PATH environment variable. If it has, either replace them with the corresponding folders of the mingw toolchain, or add the mingw folders into the PATH environment-variable BEFORE tdm-gcc's.
    "Talk is cheap, show me the code" - Linus Torvalds

  10. #10
    Registered User
    Join Date
    May 2015
    Posts
    52
    I'm actually sad I didn't get to you faster on that, I just solved it before I saw your response. Instead of tampering with the compiler and linker settings, I added the libraries immediately to the "link libraries" window, and it works.

    Still doesn't produce the outcome I wanted, but I'll try to work it out. Nothing wrong with the program, though. It just doesn't preserve transparency for some reason. I'll see what I can do.

  11. #11
    Registered User migf1's Avatar
    Join Date
    May 2013
    Location
    Athens, Greece
    Posts
    385
    Quote Originally Posted by Sotos View Post
    I'm actually sad I didn't get to you faster on that, I just solved it before I saw your response.
    No problem, perhaps it proves handy to other people searching for the same thing. I'm glad you solved it.

    Instead of tampering with the compiler and linker settings, I added the libraries immediately to the "link libraries" window, and it works.
    I guess it has to do with what forms of gtk2 libs you passed to the ide (.lib or .dll.a) and where you passed them.

    Still doesn't produce the outcome I wanted, but I'll try to work it out. Nothing wrong with the program, though. It just doesn't preserve transparency for some reason. I'll see what I can do.
    What do you mean when you say "it doesn't preserve transparency"?
    "Talk is cheap, show me the code" - Linus Torvalds

  12. #12
    Registered User
    Join Date
    May 2015
    Posts
    52
    Quote Originally Posted by migf1 View Post
    What do you mean when you say "it doesn't preserve transparency"?
    Well, this
    Gdk-pixbuf and file locations (and other GTK+ questions)-shield-png
    is the image I used, and this
    Gdk-pixbuf and file locations (and other GTK+ questions)-nontransparent-jpg
    is what I got.

    I actually searched online, and I could find no way to make part of a window transparent. In this case, I'd like everything but the shield itself to be transparent. I could make a totally transparent window (though I haven't figured this one out either) and slap the image on top of it, I guess, but I'd also like to make partly transparent buttons of the same type (i.e. circular instead of square, with the rest of the square being transparent).
    Any help would be greatly appreciated.

  13. #13
    Registered User migf1's Avatar
    Join Date
    May 2013
    Location
    Athens, Greece
    Posts
    385
    I see... Perhaps GtkImage widgets are an easier option for what you're after.

    For example, instead of setting the image directly as the background of the window, you can create an image widget and use it as a the main container of your window.

    For example the following code uses this technique. It also resizes the image-widget when the window gets resized (via the "configure-event"), although the window is not allowed to get a smaller size than the original dimensions of the image...

    Code:
    #include <gtk/gtk.h>
    
    gboolean resize_image(GtkWidget *image, GdkEvent *event, GtkWidget *window)
    {
        GdkPixbuf *pixbuf = gtk_image_get_pixbuf( GTK_IMAGE(image) );
        if ( pixbuf == NULL ) {
            g_printerr("Failed to resize image\n");
            return 1;
        }
        
    //    printf("Width: %i\nHeight%i\n", image->allocation.width, image->allocation.height);
        
        pixbuf = gdk_pixbuf_scale_simple(
                pixbuf,
                image->allocation.width,
                image->allocation.height,
                GDK_INTERP_BILINEAR
                );
        
        gtk_image_set_from_pixbuf( GTK_IMAGE(image), pixbuf );
        
        return FALSE;
    }
    
    int main( int argc, char **argv )
    {
        const gchar *FNAME_BGIMAGE = "Shield.png";
        GtkWidget *window = NULL;
        GtkWidget *image = NULL;
    
        /* Initialize */
        gtk_init( &argc, &argv );
        
        /* Create Widgets */
        window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
        image = gtk_image_new_from_file( FNAME_BGIMAGE );
        if (image == NULL) {
            g_printerr("Could not open \"%s\"\n", FNAME_BGIMAGE);
            return EXIT_FAILURE;
        }
        
        /* attach standard event handlers */
        g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
        g_signal_connect(image, "configure-event", G_CALLBACK(resize_image), (gpointer)window);
    
       /* add the image-widget as a container to the window */
        gtk_container_add( GTK_CONTAINER(window), image );
    
        gtk_widget_show_all( GTK_WIDGET(window) );
        gtk_main();
    
        return 0;
    }
    The resizing behavior of any widget depends on the packing options of its container.

    Btw, Glade (the RAD tool for GTK apps) takes away a lot of such details for the initial design of your GTK app.

    Another important thing to remember is that GtkImage widgets do NOT respond to click-events. If you need to handle clicks on images, you have to wrap them within a clickable container (such as a hbox, a vbox, or a button widget) and handle clicks on those.

    Anyway, I suggest you start humble and follow a few tutorials for beginners, before moving on to more advanced topics. There's a bit of theory behind GTK which you should be familiar with.

    Also, have a look at Glade. Play with it a bit (after you have learned GTK basics) because it can greatly simplify the code for the original design of your UI... still you need to know how to handle things without Glade though, e.g. for changing widgets dynamically - that is, after they have been loaded from the glade file.

    PS1. Regarding what you asked in your last post, about making your own buttons, handle image transparencies by yourself, etc, although it is do-able with GTK (via sub-classing a widget for example), I would advice against it. Try to stick with the ready-made widgets and their provided methods. Chances are that they cover most of your needs.

    Moreover, you can make quite a few customizations via gtk rc files and its corresponding api. Or dynamically with the gtk_style api (this link may also prove useful).

    PS2. On a side note, make sure you indeed need a GUI framework, because I think a game/multimedia library may be more close to what you are after (sdl2, allegro5, csfml2, etc).

    PS3. Btw, if you want to get rid of the console window (probably for your Release build) append the "-mwindows" option to gcc's command-line.
    Last edited by migf1; 06-30-2015 at 03:48 AM.
    "Talk is cheap, show me the code" - Linus Torvalds

  14. #14
    Registered User
    Join Date
    May 2015
    Posts
    52
    Well, here I am again, I was on vacation for a while.

    While the game was proceeding rapidly, this last month I've been at a standstill regarding the UI and how I'd produce one. I really want to get familiar with something and start working with it, and GTK seemed like a good option.
    Now, to be honest, I've no idea if it is indeed the best for me, and I don't know whether I should be looking at a game library like you suggested. Since it seems like a long term project, I'd like to not have to learn a library and then throw it away. So, let me sum up exactly what I want. I'd appreciate any advice you can give me, as I can't really judge without going deep into each library and learning it.
    I have the game code (or parts thereof) and I want to create a user interface more elegant and better looking than the console. Ideally, I'd like the end product to look similar to, say, the League of Legends client ( http://i.imgur.com/rmdqUxL.jpg ), though way less cluttered. I want my game's client to have an output window that would cover most of the client and would show the text for the user to read (remember, it's only a text-based game), a small input bar where the user can input commands, close / minimize buttons and optionally some bars (for stats like health), numbers (for stats like, say, attack) and a minimap (which I have already coded and produced in the console, composing it of ascii characters like ▓▒░).
    So, all in all, I want a library that can
    •Create a window and hide its decorations (like in gtk_window_set_decorated)
    •Assign a background image to said window, either immediately or by using some other function (like another widget on top) and possibly keep part of it transparent
    •Create text boxes for input / output, show numbers and possibly bars or custom graphics (like a small window with the minimap, which can essentially be rows of ascii characters)
    •Create buttons for various functions (minimize / close / enter text), assign images to said buttons and possibly, though not necessarily, keep parts of them transparent

    Other than the text boxes, I believe I can work things out with the rest just with GTK. Now that I think about it, the partial transparency is quite easily avoided too.
    I sadly don't know how to control text boxes or show dynamic text (like stats that change during the game, or health bars that are composed of ascii characters), which I can use help with.

    I'm open to suggestions, if you think another library will work better, I'll give it a try.
    I'm also a bit worried that I'm pestering you too much. I don't demand any help, you've already done way more than enough and I thank you. Still, it's nice to have a helping hand when venturing out into unknown territory.

  15. #15
    Registered User migf1's Avatar
    Join Date
    May 2013
    Location
    Athens, Greece
    Posts
    385
    Hello, I hope you had a great time during your vacation

    The things you have described can be done with GTK.

    Some hints:

    - For laying out your widgets, try putting them inside GtkHBox and/or GtkVBox widgets, with the desired packing options.

    - For clickable images, try putting GtkImage widgets inside GtkEventBox widgets (the reason is that GtkImages are not clickable, but GtkEventBoxes are).

    - For creating & manipulating text-boxes, try using the GtkEntry methods.

    - For creating & manipulating progress-bars, try using the GtkProgressBar methods.

    - For custom drawing, try using a GtkDrawingArea widget, then on its "expose-event" create a Cairo graphics context for the widget's ->window, via the Cairo Interaction methods. Then you can start drawing via the Drawing Primitives interface. Read some tutorials for this, because it is a bit complicated at first (Cairo is a stand alone graphics library, but GTK2 uses it anyway for all its drawing needs... for example a GtkWindow uses GdkWindows for drawing, the same does a GtkButton etc... see this for details about the difference between Gtk and Gdk).
    "Talk is cheap, show me the code" - Linus Torvalds

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Tictactoe x and o locations.
    By xTonyLeo in forum C Programming
    Replies: 10
    Last Post: 01-27-2013, 06:12 PM
  2. New pointer locations
    By mica in forum C Programming
    Replies: 2
    Last Post: 03-23-2011, 08:31 AM
  3. Benifits of differnt file locations
    By peckitt99 in forum Tech Board
    Replies: 3
    Last Post: 08-22-2007, 12:16 PM
  4. writing to certain locations.
    By epidemic in forum C++ Programming
    Replies: 2
    Last Post: 12-19-2006, 12:12 PM
  5. file i/o locations
    By algi in forum C++ Programming
    Replies: 4
    Last Post: 01-16-2005, 11:21 AM