| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 | {  This file extracted from the GTK tutorial.  list.c  Converted from C to Pascal by Frank Loemker  <[email protected]>}program list;uses  glib,gdk,gtk;{ this is our data identification string to store data in list items }const  list_item_data_key : pgchar = 'list_item_data';Function itos (I : Longint) : String;Var S : String[15];begin  Str (I,S);  itos:=S;end;{ this is the signal handler that got connected to button  press/release events of the GtkList }procedure sigh_button_event (gtklist: pGtkWidget;event:pGdkEventButton;frame:pGtkWidget);cdecl;var  dlist, free_list : pGList;  new_prisoner     : pGtkWidget;  list_item        : pGtkWidget;begin  { we only do something if the third (rightmost mouse button    was released }  if (event^.thetype=GDK_BUTTON_RELEASE) and     (event^.button=1) then   begin      { fetch the currently selected list item which        will be our next prisoner ;) }      dlist := pGTKLIST(gtklist)^.selection;      if dlist<>nil then        new_prisoner := pGTKWIDGET(dlist^.data)      else        new_prisoner := nil;      { look for already prisoned list items, we        will put them back into the list        remember to free the doubly linked list that        gtk_container_children() returns }      dlist := gtk_container_children(pGTKCONTAINER(frame));      free_list := dlist;      while dlist<>nil do       begin         list_item := dlist^.data;         gtk_widget_reparent(list_item, gtklist);         dlist := dlist^.next;       end;      g_list_free(free_list);      { if we have a new prisoner, remove him from the        GtkList and put him into the frame 'Prison'        we need to unselect the item before }      if new_prisoner<>nil then       begin         gtk_list_unselect_child(pGTKLIST(gtklist),new_prisoner);         gtk_widget_reparent(new_prisoner, frame);       end;    end;end;{ this is the signal handler that gets called if GtkList  emits the 'selection_changed' signal }procedure sigh_print_selection (gtklist   : pGtkWidget;func_data : gpointer);cdecl;var dlist          : pGList;  list_item        : pGtkObject;  item_data_string : pgchar;begin  { fetch the doubly linked list of selected items    of the GtkList, remember to treat this as read-only! }  dlist := pGTKLIST(gtklist)^.selection;  { if there are no selected items there is nothing more    to do than just telling the user so }  if dlist=nil then   writeln ('Selection cleared')  else   begin     { ok, we got a selection and so we print it }     write ('The selection is a ');     { get the list item from the doubly linked list       and then query the data associated with list_item_data_key       we then just print it }     while dlist<>nil do      begin        list_item := pGTKOBJECT(dlist^.data);        item_data_string := gtk_object_get_data(list_item,list_item_data_key);        write (pchar(item_data_string),' ');        dlist := dlist^.next;      end;     writeln;   end;end;{ main function to set up the user interface }var  separator, window, vbox, scrolled_window,  frame, thelist, button, list_item : pGtkWidget;  dlist                             : pGList;  i                                 : guint;  buffer                            : array [0..63] of gchar;  thelabel                          : pGtkWidget;  str                               : pgchar;begin  { initialize gtk+ (and subsequently gdk) }  gtk_init(@argc, @argv);  gtk_rc_init;  { create a window to put all the widgets in    connect gtk_main_quit() to the 'destroy' event of    the window to handle window manager close-window-events }  window := gtk_window_new(GTK_WINDOW_TOPLEVEL);  gtk_window_set_title(pGTKWINDOW(window), 'GtkList Example');  gtk_signal_connect(pGTKOBJECT(window),'destroy',GTK_SIGNAL_FUNC(@gtk_main_quit),nil);  { inside the window we need a box to arrange the widgets    vertically }  vbox := gtk_vbox_new(false, 5);  gtk_container_set_border_width(pGTKCONTAINER(vbox), 5);  gtk_container_add(pGTKCONTAINER(window), vbox);  { this is the scolled window to put the GtkList widget inside }  scrolled_window := gtk_scrolled_window_new(nil, nil);  gtk_widget_set_usize(scrolled_window, 250, 150);  gtk_box_pack_start (pGTKBOX(vbox), scrolled_window, true, true, 0);  { create the GtkList widget    connect the sigh_print_selection() signal handler    function to the 'selection_changed' signal of the GtkList    to print out the selected items each time the selection    has changed }  thelist := gtk_list_new();  gtk_list_set_selection_mode (pGtkList(thelist),GTK_SELECTION_BROWSE);  gtk_scrolled_window_add_with_viewport (pGtkScrolledWindow(scrolled_window), thelist);  gtk_signal_connect(pGTKOBJECT(thelist),'selection_changed',GTK_SIGNAL_FUNC(@sigh_print_selection),nil);  { we create a 'Prison' to put a list item in ;) }  frame := gtk_frame_new('Prison');  gtk_widget_set_usize(frame, 200, 50);  gtk_container_set_border_width(pGTKCONTAINER(frame), 5);  gtk_frame_set_shadow_type(pGTKFRAME(frame), GTK_SHADOW_OUT);  gtk_box_pack_start (pGTKBOX(vbox), frame, false, true, 0);  { connect the sigh_button_event() signal handler to the GtkList    wich will handle the 'arresting' of list items }  gtk_signal_connect(pGTKOBJECT(thelist),'button_release_event',GTK_SIGNAL_FUNC(@sigh_button_event),frame);  { create a separator }  separator := gtk_hseparator_new();  gtk_box_pack_start (pGTKBOX(vbox), separator, false, true, 0);  { finaly create a button and connect it's 'clicked' signal    to the destroyment of the window }  button := gtk_button_new_with_label('Close');  gtk_box_pack_start (pGTKBOX(vbox), button, false, true, 0);  gtk_signal_connect_object(pGTKOBJECT(button),'clicked',GTK_SIGNAL_FUNC(@gtk_widget_destroy),pGTKOBJECT(window));  { now we create 5 list items, each having it´s own    label and add them to the GtkList using gtk_container_add()    also we query the text string from the label and    associate it with the list_item_data_key for each list item }  for i := 0 to 4 do   begin     buffer:='ListItemContainer with Label #'+itos(i)+#0;     thelabel := gtk_label_new(buffer);     list_item := gtk_list_item_new();     gtk_container_add(pGTKCONTAINER(list_item), thelabel);     gtk_container_add(pGTKCONTAINER(thelist), list_item);     gtk_label_get(pGTKLABEL(thelabel), @str);     gtk_object_set_data(pGTKOBJECT(list_item),list_item_data_key,str);   end;  { here, we are creating another 5 labels, this time    we use gtk_list_item_new_with_label() for the creation    we can't query the text string from the label because    we don't have the labels pointer and therefore    we just associate the list_item_data_key of each    list item with the same text string    for adding of the list items we put them all into a doubly    linked list (GList), and then add them by a single call to    gtk_list_append_items()    because we use g_list_prepend() to put the items into the    doubly linked list, their order will be descending (instead    of ascending when using g_list_append()) }  dlist := nil;  for i:=5 to 9 do   begin     buffer:='List Item with Label '+itos(i)+#0;     list_item := gtk_list_item_new_with_label(buffer);     dlist := g_list_prepend(dlist, list_item);     gtk_object_set_data(pGTKOBJECT(list_item),list_item_data_key,pchar('ListItem with integrated Label'));   end;  gtk_list_append_items(pGTKLIST(thelist), dlist);  { finaly we want to see the window, don't we? ;) }  gtk_widget_show_all(window);  { fire up the main event loop of gtk }  gtk_main();  { we get here after gtk_main_quit() has been called which    happens if the main window gets destroyed }end.
 |