Joel GTK+ Guru
Joined: 06 Apr 2008 Posts: 174 Location: Fortress of solitude
|
Posted: Sat Nov 15, 2008 3:43 am Post subject: My ListBox v1.0 |
|
|
The purpose of this project is to use a simple listbox to add string or edit the inputed ones. The project focus on the following widgets:
- treeview
- Scrolled window
- menubar
- MessageDialog
You can compile with:
| Code: (Plaintext) | 1 2 3
|
gcc fun.c main.c -o mylistbox_1.0 `pkg-config --cflags --libs gtk+-2.0`
|
main.h
| Code: (C) | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
#ifndef MY_HEADER_WIDGETS
#define MY_HEADER_WIDGETS
// Function prototypes and stuff used in main.c
typedef struct {
GtkWidget *window1; // window1 is the parent window handle
GtkWidget *entry1; // entry1 will hold the selected text on treeview or inputed text
GtkWidget *treeview1; //treeview1 => a nice listbox style treeview
} MYWIDGETS, *PMYWIDGETS;
void window1_destroy(GtkWidget *widget, gpointer data);
gboolean window1_delete_event(GtkWidget *widget, GdkEvent *event, gpointer data);
GtkWidget* gtk_list_box_new(GtkTreeModel* model, const gchar *str);
void gtk_list_box_add(GtkTreeModel *model, const gchar *str);
void button1_clicked(GtkWidget *button, gpointer data);
void button2_clicked(GtkWidget *button, gpointer data);
void treeview1_changed(GtkTreeSelection *treeselection, gpointer user_data);
gboolean entry1_key_press_event(GtkWidget *entry, GdkEventKey *event, gpointer user_data);
GtkWidget* gtk_my_menu_bar_new(GtkWidget *box);
GtkWidget* gtk_my_submenu_new(GtkWidget *menubar, const gchar *str);
GtkWidget* gtk_my_submenu_item(GtkWidget *submenu, const gchar *str);
void exit_activate(GtkMenuItem *menuitem, gpointer user_data);
void me_activate(GtkMenuItem *menuitem, gpointer user_data);
#endif
|
func.c
| Code: (C) | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
|
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include "main.h"
// a nice messagebox to inform stuff
// parent => widget of our top window
// title => title of our MsgBox
// type => see the docs about GtkMessageType
// primtext => primary text (markup style)
// sectext => secundary text (markup style)
void MsgBox(GtkWidget *parent, GtkMessageType type, const gchar *title, const gchar *primtext, const gchar *sectext) {
// create the messagebox widget
GtkWidget *mb = gtk_message_dialog_new_with_markup(GTK_WINDOW(parent), GTK_DIALOG_DESTROY_WITH_PARENT, type, GTK_BUTTONS_OK, "%s", primtext);
// add a nice title
gtk_window_set_title(GTK_WINDOW(mb), title);
// add the secundary text
gtk_message_dialog_format_secondary_markup(GTK_MESSAGE_DIALOG(mb), "%s", sectext);
// show it
gtk_dialog_run(GTK_DIALOG(mb));
// after a button is clicked, bye bye
gtk_widget_destroy(mb);
}
// bye bye gtk :(
void gtk_bye_bye(void) {
gtk_main_quit();
}
// wrapper to create the menubar
// box => panel which is going to attach
GtkWidget* gtk_my_menu_bar_new(GtkWidget *box) {
// create the menubar
GtkWidget *mb = gtk_menu_bar_new();
// attach mb => box
gtk_box_pack_start(GTK_BOX(box), mb, FALSE, FALSE, 0);
// return the menubar handle
return mb;
}
// function to create a new submenu item
GtkWidget* gtk_my_submenu_new(GtkWidget *menubar, const gchar *str) {
GtkWidget *submenu = gtk_menu_new();
GtkWidget *menu_item = gtk_menu_item_new_with_mnemonic(str);
gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item), submenu);
gtk_menu_shell_append(GTK_MENU_SHELL(menubar), menu_item);
return submenu;
}
// function to add items in the submenu
GtkWidget* gtk_my_submenu_item(GtkWidget *submenu, const gchar *str) {
// create the new item
GtkWidget *submenu_item = gtk_image_menu_item_new_from_stock(str, NULL);
// attach the new item to the submenu
gtk_menu_shell_append(GTK_MENU_SHELL(submenu), submenu_item);
return submenu_item;
}
// our window is going bye bye
void window1_destroy(GtkWidget *widget, gpointer data) {
gtk_bye_bye();
}
// we recived a bye bye event: true we stay :) false we don't :(
gboolean window1_delete_event(GtkWidget *widget, GdkEvent *event, gpointer data) {
// Useful to ask "Do you want to exit"
return FALSE;
}
// to simplify the code, let's make a function to create the "listbox"
// model => the new model of the "listbox"
// str => the title of the "listbox"
GtkWidget* gtk_list_box_new(GtkTreeModel* model, const gchar *str) {
// create the treeview with the new model
GtkWidget *lb = gtk_tree_view_new_with_model(model);
// we are going to use strings in the cells
GtkCellRenderer *cell_render = gtk_cell_renderer_text_new();
// Add the single column that will need
gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(lb), -1, str, cell_render, "text", 0, NULL);
// return the lb widget handle
return lb;
}
// add items in the "listbox"
// model => treeview's model handle
// str => string to add
void gtk_list_box_add(GtkTreeModel *model, const gchar *str) {
// iter to use list
GtkTreeIter iter;
// find last position in the list
gtk_list_store_append(GTK_LIST_STORE(model), &iter);
// add our string
gtk_list_store_set(GTK_LIST_STORE(model), &iter, 0, str, -1);
return;
}
// the function for the signal clicked from button1
void button1_clicked(GtkWidget *button, gpointer user_data) {
// get the struct passed in the signal handler
PMYWIDGETS pmw = (PMYWIDGETS)user_data;
// len of the entry1
int len = gtk_entry_get_text_length(GTK_ENTRY(pmw->entry1));
// see if len is not equal to zero
if (len != 0) {
// the "listbox" model
GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(pmw->treeview1));
// data to get from the entry1
const gchar *data = gtk_entry_get_text(GTK_ENTRY(pmw->entry1));
// add the data :)
gtk_list_box_add(model, data);
// add a cool "add" effect -_-
gtk_entry_set_text(GTK_ENTRY(pmw->entry1), "");
// and keep the focus
gtk_widget_grab_focus(pmw->entry1);
}
else {
// tell that we need a text to add to "listbox"
//g_print("Please input a text to add to the listbox\n");
MsgBox(pmw->window1, GTK_MESSAGE_ERROR, "Error", "No text was input", "Please <span><u>input a text to add</u></span> to the listbox");
// and keep the focus
gtk_widget_grab_focus(pmw->entry1);
}
}
// the function for the signal clicked from button2
void button2_clicked(GtkWidget *button, gpointer user_data) {
// get the struct passed in the signal handler
PMYWIDGETS pmw = (PMYWIDGETS)user_data;
// len of the entry1
int len = gtk_entry_get_text_length(GTK_ENTRY(pmw->entry1));
// see if len is not equal to zero
if (len != 0) { // we have data so..
GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(pmw->treeview1));
// model of the "listbox"
GtkTreeModel *model;
// iter of the position to edit
GtkTreeIter iter;
// now detect if we selected something in the "listbox"
if (gtk_tree_selection_get_selected(sel, &model, &iter)) { // yay! item is selected
// get the data :)
const gchar *data = gtk_entry_get_text(GTK_ENTRY(pmw->entry1));
// edit it!
gtk_list_store_set(GTK_LIST_STORE(model), &iter, 0, data, -1);
// and keep the focus
gtk_widget_grab_focus(pmw->entry1);
}
else {
// tell that we need some item to edit -_-
//g_print("Please select an item from the listbox\n");
MsgBox(pmw->window1, GTK_MESSAGE_ERROR, "Error", "No item was inputed", "Please <span><b>select an item</b></span> from the listbox");
}
}
else {
// tell that we need some string to edit -_-
//g_print("Please write a text in to modify the selected item from the listbox\n");
MsgBox(pmw->window1, GTK_MESSAGE_ERROR, "Error", "No text was inputed", "Please <span><b>write a text</b></span> in to modify the selected item from the listbox");
}
}
// the function for the signal "key-press-event" from entry1
gboolean entry1_key_press_event(GtkWidget *entry, GdkEventKey *event, gpointer user_data) {
// capture <enter> key
if (event->keyval == GDK_Return) {
// tell that we need one option "add" or "edit"
// g_print("No enter please: use add or edit\n");
// get entry's widget toplevel (parent handle if you will)
GtkWidget *toplevel = gtk_widget_get_toplevel(entry);
MsgBox(toplevel, GTK_MESSAGE_INFO, "Information", "No enter please", "Use <span><b>add</b> or <b>edit</b></span> buttons");
}
// let it be :)
return FALSE;
}
// the function for the signal "changed" from treeview's treeselection
void treeview1_changed(GtkTreeSelection *treeselection, gpointer user_data) {
// pointer to the item selected (if)
GtkTreeIter iter;
// model of the treeview
GtkTreeModel *model;
// see if we have an item selected
if (gtk_tree_selection_get_selected(treeselection, &model, &iter)) {
// get the struct passed in the signal handler
PMYWIDGETS pmw = (PMYWIDGETS)user_data;
// var for the retrived data
gchar *data;
// get the data :)
gtk_tree_model_get(model, &iter, 0, &data, -1);
// print the data in our entry1
gtk_entry_set_text(GTK_ENTRY(pmw->entry1), data);
// free data
g_free(data);
}
}
// the function fired up when user selects "exit" on the menubar
void exit_activate(GtkMenuItem *menuitem, gpointer user_data) {
gtk_bye_bye();
}
// the function fired up when user selects "me" on the menubar
void me_activate(GtkMenuItem *menuitem, gpointer user_data) {
//gtk_show_uri(NULL, "http://codevault.tuxfamily.org", GDK_CURRENT_TIME, NULL);
GtkWidget *parent = GTK_WIDGET(user_data);
MsgBox(parent, GTK_MESSAGE_INFO, "About me", "My ListBox v1.0 - Brenda", "Author: Joel\nEmail: aullidolunar (at-@) gM4il (.dot.) c0m\nLicense: GPL (http://www.gnu.org/copyleft/gpl.html)\ncode vault: http://codevault.tuxfamily.org.");
}
|
main.c
| Code: (C) | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
#include <gtk/gtk.h>
#include "main.h"
int main(int argc, char *argv[]) {
// a single instance of our struct
MYWIDGETS mw = {0};
// panel1 => the panel widget that will hold all the rest of them
GtkWidget *panel1;
// label1 => our first label
GtkWidget *label1;
// label1_a => is the widget that will align our entry to the left :)
GtkWidget *label1_a;
// buttons1 => a sub panel with a few buttons
GtkWidget *buttons1;
// button1 => a button labeled "add"
GtkWidget *button1;
// button2 => a button labeled "edit"
GtkWidget *button2;
// store => the treeview1 store model
GtkListStore *store;
// scroll => window widget for add scrollbars in the treeview1
GtkWidget *scroll;
// treesel => to get the "changed" signal from the treeview1
GtkTreeSelection *treesel;
// menubar => the main menu bar widget
GtkWidget *menubar;
// submenu1 => submenu item named "File"
GtkWidget *submenu1;
// exit => exit item menu
GtkWidget *exit;
// submenu2 => submenu item named "About"
GtkWidget *submenu2;
// me => me item menu
GtkWidget *me;
// init the gtk library
gtk_init(&argc, &argv);
// create our top window
mw.window1 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
// Sets the border width of our window
gtk_container_set_border_width(GTK_CONTAINER(mw.window1), 10);
// Add some nice title to our window
gtk_window_set_title(GTK_WINDOW(mw.window1), "My ListBox v1.0 - Brenda");
// our window will have some nice dimmensions
gtk_window_set_default_size(GTK_WINDOW(mw.window1), 300, 350);
// our window will be in the center of the screen
gtk_window_set_position(GTK_WINDOW(mw.window1), GTK_WIN_POS_CENTER);
// trap the delete_event signal
g_signal_connect(G_OBJECT(mw.window1), "delete_event", G_CALLBACK(window1_delete_event), NULL);
// trap the delete signal
g_signal_connect(G_OBJECT(mw.window1), "destroy", G_CALLBACK(window1_destroy), NULL);
// panel1 creation
panel1 = gtk_vbox_new(FALSE, 0),
// attach panel1 => window1
gtk_container_add(GTK_CONTAINER(mw.window1), panel1);
// menubar creation
menubar = gtk_my_menu_bar_new(panel1);
// submenu1 creation for "File"
submenu1 = gtk_my_submenu_new(menubar, "_File");
exit = gtk_my_submenu_item(submenu1, GTK_STOCK_QUIT);
g_signal_connect(exit, "activate", G_CALLBACK(exit_activate), NULL);
// submenu1 creation for "About"
submenu2 = gtk_my_submenu_new(menubar, "_About");
me = gtk_my_submenu_item(submenu2, "_Me");
g_signal_connect(me, "activate", G_CALLBACK(me_activate), mw.window1);
// label1_a creation
label1_a = gtk_alignment_new(0, 0.5, 0, 0);
// label1 creation
label1 = gtk_label_new("Please input some text:");
// add label1 => label1_a
gtk_container_add(GTK_CONTAINER(label1_a), label1);
// attach label1 => panel1
gtk_box_pack_start(GTK_BOX(panel1), label1_a, FALSE, FALSE, 0);
// entry1 creation
mw.entry1 = gtk_entry_new();
// attach entry1 => panel1
gtk_box_pack_start(GTK_BOX(panel1), mw.entry1, FALSE, FALSE, 0);
// buttons1 creation
buttons1 = gtk_hbox_new(FALSE, 0);
// attach buttons1 => panel1
gtk_box_pack_start(GTK_BOX(panel1), buttons1, FALSE, FALSE, 0);
// button1 creation
button1 = gtk_button_new_from_stock(GTK_STOCK_ADD);
// attach button1 => buttons1
gtk_box_pack_start(GTK_BOX(buttons1), button1, TRUE, FALSE, 0);
// button2 creation
button2 = gtk_button_new_from_stock(GTK_STOCK_EDIT);
// attach button1 => buttons1
gtk_box_pack_start(GTK_BOX(buttons1), button2, TRUE, FALSE, 0);
// store creaton
store = gtk_list_store_new(1, G_TYPE_STRING);
// treeview1 creation
mw.treeview1 = gtk_list_box_new(GTK_TREE_MODEL(store), "My Items");
// get treesel signal
treesel = gtk_tree_view_get_selection(GTK_TREE_VIEW(mw.treeview1));
// scroll creation
scroll = gtk_scrolled_window_new(NULL, NULL);
// add the policies
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
// attach treeview1 => scroll
gtk_container_add(GTK_CONTAINER(scroll), mw.treeview1);
// attach scroll => panel1
gtk_box_pack_start(GTK_BOX(panel1), scroll, TRUE, TRUE, 0);
// add some nice strings :)
gtk_list_box_add(GTK_TREE_MODEL(store), "C");
gtk_list_box_add(GTK_TREE_MODEL(store), "gtk");
gtk_list_box_add(GTK_TREE_MODEL(store), "GIMP");
gtk_list_box_add(GTK_TREE_MODEL(store), "Geany");
gtk_list_box_add(GTK_TREE_MODEL(store), "gnome");
gtk_list_box_add(GTK_TREE_MODEL(store), "Ubuntu");
// unref the store
g_object_unref(store);
// some signals to deal with :)
g_signal_connect(button1, "clicked", G_CALLBACK(button1_clicked), &mw);
g_signal_connect(button2, "clicked", G_CALLBACK(button2_clicked), &mw);
g_signal_connect(treesel, "changed", G_CALLBACK(treeview1_changed), &mw);
g_signal_connect(mw.entry1, "key-press-event", G_CALLBACK(entry1_key_press_event), NULL);
// show all widgets
gtk_widget_show_all(mw.window1);
// must be the main loop
gtk_main();
return 0;
}
|
Screenshot:
 |
|