gtk3 3.0.5 → 3.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/ext/gtk3/rb-gtk3-cell-layout.c +42 -0
  3. data/ext/gtk3/rb-gtk3-private.h +3 -0
  4. data/ext/gtk3/rb-gtk3-tree-model.c +77 -0
  5. data/ext/gtk3/rb-gtk3-tree-view.c +42 -0
  6. data/ext/gtk3/rb-gtk3.c +33 -0
  7. data/lib/gtk3/builder.rb +54 -11
  8. data/lib/gtk3/container.rb +13 -0
  9. data/lib/gtk3/deprecated.rb +4 -4
  10. data/lib/gtk3/loader.rb +2 -0
  11. data/lib/gtk3/show-uri.rb +34 -0
  12. data/lib/gtk3/stock-item.rb +36 -0
  13. data/lib/gtk3/tree-iter.rb +3 -1
  14. data/sample/gtk-demo/TODO +1 -1
  15. data/sample/gtk-demo/alias_cursor.png +0 -0
  16. data/sample/gtk-demo/all_scroll_cursor.png +0 -0
  17. data/sample/gtk-demo/application.ui +11 -18
  18. data/sample/gtk-demo/brick.png +0 -0
  19. data/sample/gtk-demo/brick2.png +0 -0
  20. data/sample/gtk-demo/cell_cursor.png +0 -0
  21. data/sample/gtk-demo/col_resize_cursor.png +0 -0
  22. data/sample/gtk-demo/copy_cursor.png +0 -0
  23. data/sample/gtk-demo/crosshair_cursor.png +0 -0
  24. data/sample/gtk-demo/css_accordion.css +1 -2
  25. data/sample/gtk-demo/css_basics.css +1 -1
  26. data/sample/gtk-demo/css_multiplebgs.css +136 -0
  27. data/sample/gtk-demo/css_pixbufs.css +76 -0
  28. data/sample/gtk-demo/css_shadows.css +44 -0
  29. data/sample/gtk-demo/cssview.css +41 -0
  30. data/sample/gtk-demo/decor1.png +0 -0
  31. data/sample/gtk-demo/decor2.png +0 -0
  32. data/sample/gtk-demo/default_cursor.png +0 -0
  33. data/sample/gtk-demo/demo.gresource.xml +216 -0
  34. data/sample/gtk-demo/demo.ui +285 -241
  35. data/sample/gtk-demo/e_resize_cursor.png +0 -0
  36. data/sample/gtk-demo/ew_resize_cursor.png +0 -0
  37. data/sample/gtk-demo/filtermodel.ui +195 -0
  38. data/sample/gtk-demo/font-features.ui +966 -0
  39. data/sample/gtk-demo/glarea-fragment.glsl +9 -0
  40. data/sample/gtk-demo/glarea-vertex.glsl +8 -0
  41. data/sample/gtk-demo/grab_cursor.png +0 -0
  42. data/sample/gtk-demo/grabbing_cursor.png +0 -0
  43. data/sample/gtk-demo/hand_cursor.png +0 -0
  44. data/sample/gtk-demo/help_cursor.png +0 -0
  45. data/sample/gtk-demo/listbox.ui +332 -0
  46. data/sample/gtk-demo/main.rb +132 -313
  47. data/sample/gtk-demo/main.ui +190 -0
  48. data/sample/gtk-demo/markup.txt +16 -0
  49. data/sample/gtk-demo/menus.ui +1 -1
  50. data/sample/gtk-demo/messages.txt +388 -0
  51. data/sample/gtk-demo/modelbutton.ui +162 -0
  52. data/sample/gtk-demo/move_cursor.png +0 -0
  53. data/sample/gtk-demo/n_resize_cursor.png +0 -0
  54. data/sample/gtk-demo/ne_resize_cursor.png +0 -0
  55. data/sample/gtk-demo/nesw_resize_cursor.png +0 -0
  56. data/sample/gtk-demo/no_drop_cursor.png +0 -0
  57. data/sample/gtk-demo/none_cursor.png +0 -0
  58. data/sample/gtk-demo/not_allowed_cursor.png +0 -0
  59. data/sample/gtk-demo/ns_resize_cursor.png +0 -0
  60. data/sample/gtk-demo/nw_resize_cursor.png +0 -0
  61. data/sample/gtk-demo/nwse_resize_cursor.png +0 -0
  62. data/sample/gtk-demo/org.gtk.Demo.gschema.xml +17 -0
  63. data/sample/gtk-demo/pointer_cursor.png +0 -0
  64. data/sample/gtk-demo/popover.ui +94 -0
  65. data/sample/gtk-demo/progress_cursor.png +0 -0
  66. data/sample/gtk-demo/reset.css +0 -1
  67. data/sample/gtk-demo/revealer.ui +177 -0
  68. data/sample/gtk-demo/row_resize_cursor.png +0 -0
  69. data/sample/gtk-demo/s_resize_cursor.png +0 -0
  70. data/sample/gtk-demo/scale.ui +117 -0
  71. data/sample/gtk-demo/se_resize_cursor.png +0 -0
  72. data/sample/gtk-demo/spinbutton.ui +194 -0
  73. data/sample/gtk-demo/stack.ui +72 -0
  74. data/sample/gtk-demo/sw_resize_cursor.png +0 -0
  75. data/sample/gtk-demo/text_cursor.png +0 -0
  76. data/sample/gtk-demo/theming.ui +102 -147
  77. data/sample/gtk-demo/vertical_text_cursor.png +0 -0
  78. data/sample/gtk-demo/w_resize_cursor.png +0 -0
  79. data/sample/gtk-demo/wait_cursor.png +0 -0
  80. data/sample/gtk-demo/zoom_in_cursor.png +0 -0
  81. data/sample/gtk-demo/zoom_out_cursor.png +0 -0
  82. data/sample/tutorial/README.md +415 -0
  83. data/test/run-test.rb +1 -1
  84. data/test/test-gtk-builder.rb +108 -30
  85. data/test/test-gtk-cell-layout.rb +6 -0
  86. metadata +80 -16
@@ -521,3 +521,418 @@ In this line, given that `self` is `ExampleAppWindow` the usage of `stack` is a
521
521
  https://developer.gnome.org/gtk3/stable/ch01s04.html#id-1.2.3.12.8
522
522
 
523
523
  * exampleapp4/exampleapp.rb
524
+
525
+ An application menu is shown by GNOME shell at the top of the screen. It is meant to collect infrequently used actions that affect the whole application.
526
+ Just like the window template, we specify our application menu in a ui file, and add it as a resource to our binary.
527
+
528
+ #### Adding the menu interface
529
+
530
+ * app-menu.ui
531
+ ```xml
532
+ <?xml version="1.0"?>
533
+ <interface>
534
+ <!-- interface-requires gtk+ 3.0 -->
535
+ <menu id="appmenu">
536
+ <section>
537
+ <item>
538
+ <attribute name="label" translatable="yes">_Preferences</attribute>
539
+ <attribute name="action">app.preferences</attribute>
540
+ </item>
541
+ </section>
542
+ <section>
543
+ <item>
544
+ <attribute name="label" translatable="yes">_Quit</attribute>
545
+ <attribute name="action">app.quit</attribute>
546
+ </item>
547
+ </section>
548
+ </menu>
549
+ </interface>
550
+ ```
551
+
552
+ This menu interface is loaded and added to our application with :
553
+
554
+ ```ruby
555
+ builder = Gtk::Builder.new(:resource => "/org/gtk/exampleapp/app-menu.ui")
556
+ app_menu = builder.get_object("appmenu")
557
+ application.set_app_menu(app_menu)
558
+ ```
559
+
560
+ With this, our application has a menu with two items that we can show when clicking on the application icon in the Gnome shell.
561
+
562
+ #### Linking menu items to actions.
563
+
564
+ All the actions initialization should be done during the "startup" step, which is guaranteed to be called once for each primary application instance.
565
+
566
+ The "quit" item in the menu is implemented with this:
567
+
568
+ ```xml
569
+ <section>
570
+ <item>
571
+ <attribute name="label" translatable="yes">_Quit</attribute>
572
+ <attribute name="action">app.quit</attribute>
573
+ </item>
574
+ </section>
575
+ ```
576
+
577
+ Then we just have to create an `Gio::SimpleAction` named "quit" and configure it in order to quit the application when this action is triggered.
578
+
579
+ ```ruby
580
+ action = Gio::SimpleAction.new("quit")
581
+ action.signal_connect("activate") do |_action, parameter|
582
+ application.quit
583
+ end
584
+ application.add_action(action)
585
+
586
+ ```
587
+
588
+ #### Add accelerators for action.
589
+
590
+ An accelerator is just a keys combination that acts as a shortcut for an action.
591
+
592
+ ```ruby
593
+ quit_accels = ["<Ctrl>Q"]
594
+ action = Gio::SimpleAction.new("quit")
595
+ action.signal_connect("activate") do |_action, parameter|
596
+ application.quit
597
+ end
598
+ application.add_action(action)
599
+ application.set_accels_for_action("app.quit", quit_accels)
600
+ ```
601
+
602
+ ### A preferences dialog
603
+ https://developer.gnome.org/gtk3/stable/ch01s04.html#id-1.2.3.12.9
604
+
605
+ ### Define and store settings for an application with gschemas
606
+ * exampleapp5/exampleapp.rb
607
+
608
+ A typical application will have a some preferences that should be remembered from one run to the next. Even for our simple example application, we may want to change the font that is used for the content.
609
+ We are going to use `Gio::Settings` to store our preferences. `Gio::Settings` requires a schema that describes our settings:
610
+
611
+ ```xml
612
+ <?xml version="1.0" encoding="UTF-8"?>
613
+ <schemalist>
614
+ <schema path="/org/gtk/exampleapp/" id="org.gtk.exampleapp">
615
+ <key name="font" type="s">
616
+ <default>'Monospace 12'</default>
617
+ <summary>Font</summary>
618
+ <description>The font to be used for content.</description>
619
+ </key>
620
+ <key name="transition" type="s">
621
+ <choices>
622
+ <choice value='none'/>
623
+ <choice value='crossfade'/>
624
+ <choice value='slide-left-right'/>
625
+ </choices>
626
+ <default>'none'</default>
627
+ <summary>Transition</summary>
628
+ <description>The transition to use when switching tabs.</description>
629
+ </key>
630
+ </schema>
631
+ </schemalist>
632
+ ```
633
+
634
+ Before we can make use of this schema in our application, we need to compile it into the binary form that `Gio::Settings` expects.
635
+
636
+ ```ruby
637
+ system("glib-compile-schemas", data_path)
638
+ ```
639
+ In this command, the tool *glib-compile-schemas* searches all files with a name that ends with *.gschema.xml* and compiles it into a binary file called *gschemas.compiled*.
640
+
641
+ This binary file can be loaded and our custom schema installed at the begining of our script with:
642
+
643
+ ```ruby
644
+ Gio::SettingsSchemaSource.new(data_path,
645
+ Gio::SettingsSchemaSource.default,
646
+ false)
647
+
648
+ ```
649
+ This is the corresponding method to the function [g_settings_schema_source_new_from_directory](https://developer.gnome.org/gio/stable/gio-GSettingsSchema-GSettingsSchemaSource.html#g-settings-schema-source-new-from-directory).
650
+
651
+ As an alternative, our schema can just be loaded by using the `GSETTINGS_SCHEMA_DIR` environment variable.
652
+
653
+ ```ruby
654
+ ENV["GSETTINGS_SCHEMA_DIR"] = data_path
655
+ ```
656
+ More informations on the use of gschemas can be found [here](https://developer.gnome.org/gio/stable/gio-GSettingsSchema-GSettingsSchemaSource.html)
657
+
658
+ Next, we need to connect our settings to the widgets that they are supposed to control. One convenient way to do this is to use `Gio::Settings` bind functionality to bind settings keys to object properties, as we do here for the transition setting. The `Gio::Settings#bind` is the ruby method for the [g_settings_bind](https://developer.gnome.org/gio/stable/GSettings.html#g-settings-bind) fonction of `gio`
659
+
660
+ ```ruby
661
+ class ExampleAppWindow < Gtk::ApplicationWindow
662
+ type_register
663
+ class << self
664
+ def init
665
+ set_template(:resource => "/org/gtk/exampleapp/window.ui")
666
+ bind_template_child("stack")
667
+ end
668
+ end
669
+
670
+ def initialize(application)
671
+ super(:application => application)
672
+ settings = Gio::Settings.new("org.gtk.exampleapp")
673
+ settings.bind("transition",
674
+ stack,
675
+ "transition-type",
676
+ Gio::SettingsBindFlags::DEFAULT)
677
+ end
678
+ ...
679
+ ```
680
+
681
+ #### Configure the settings with a dialog window
682
+
683
+ * exampleapp6/exampleapp.rb
684
+
685
+ The code to connect the font setting is a little more involved, since there is no simple object property that it corresponds to, so we are not going to go into that here.
686
+ At this point, the application will already react if you change one of the settings, e.g. using the gsettings commandline tool. Of course, we expect the application to provide a preference dialog for these. So lets do that now. Our preference dialog will be a subclass of `Gtk::Dialog`, and we'll use the same techniques that we've already seen: templates, bind child widget name to method, settings bindings.
687
+
688
+ Lets start with the template.
689
+
690
+ ```xml
691
+ <?xml version="1.0" encoding="UTF-8"?>
692
+ <interface>
693
+ <!-- interface-requires gtk+ 3.8 -->
694
+ <template class="ExampleAppPrefs" parent="GtkDialog">
695
+ <property name="title" translatable="yes">Preferences</property>
696
+ <property name="resizable">False</property>
697
+ <property name="modal">True</property>
698
+ <child internal-child="vbox">
699
+ <object class="GtkBox" id="vbox">
700
+ <child>
701
+ <object class="GtkGrid" id="grid">
702
+ <property name="visible">True</property>
703
+ <property name="margin">6</property>
704
+ <property name="row-spacing">12</property>
705
+ <property name="column-spacing">6</property>
706
+ <child>
707
+ <object class="GtkLabel" id="fontlabel">
708
+ <property name="visible">True</property>
709
+ <property name="label">_Font:</property>
710
+ <property name="use-underline">True</property>
711
+ <property name="mnemonic-widget">font</property>
712
+ <property name="xalign">1</property>
713
+ </object>
714
+ <packing>
715
+ <property name="left-attach">0</property>
716
+ <property name="top-attach">0</property>
717
+ </packing>
718
+ </child>
719
+ <child>
720
+ <object class="GtkFontButton" id="font">
721
+ <property name="visible">True</property>
722
+ </object>
723
+ <packing>
724
+ <property name="left-attach">1</property>
725
+ <property name="top-attach">0</property>
726
+ </packing>
727
+ </child>
728
+ <child>
729
+ <object class="GtkLabel" id="transitionlabel">
730
+ <property name="visible">True</property>
731
+ <property name="label">_Transition:</property>
732
+ <property name="use-underline">True</property>
733
+ <property name="mnemonic-widget">transition</property>
734
+ <property name="xalign">1</property>
735
+ </object>
736
+ <packing>
737
+ <property name="left-attach">0</property>
738
+ <property name="top-attach">1</property>
739
+ </packing>
740
+ </child>
741
+ <child>
742
+ <object class="GtkComboBoxText" id="transition">
743
+ <property name="visible">True</property>
744
+ <items>
745
+ <item translatable="yes" id="none">None</item>
746
+ <item translatable="yes" id="crossfade">Fade</item>
747
+ <item translatable="yes" id="slide-left-right">Slide</item>
748
+ </items>
749
+ </object>
750
+ <packing>
751
+ <property name="left-attach">1</property>
752
+ <property name="top-attach">1</property>
753
+ </packing>
754
+ </child>
755
+ </object>
756
+ </child>
757
+ </object>
758
+ </child>
759
+ </template>
760
+ </interface>
761
+ ```
762
+ Next comes the dialog subclass.
763
+
764
+ ```ruby
765
+ class ExampleAppPrefs < Gtk::Dialog
766
+ type_register
767
+ class << self
768
+ def init
769
+ set_template(:resource => "/org/gtk/exampleapp/prefs.ui")
770
+ bind_template_child("font")
771
+ bind_template_child("transition")
772
+ end
773
+ end
774
+ def initialize(args)
775
+ parent = args[:transient_for]
776
+ bar = args[:use_header_bar]
777
+ super(:transient_for => parent, :use_header_bar => 1)
778
+ settings = Gio::Settings.new("org.gtk.exampleapp")
779
+ settings.bind("font",
780
+ font,
781
+ "font",
782
+ Gio::SettingsBindFlags::DEFAULT)
783
+ settings.bind("transition",
784
+ transition,
785
+ "active-id",
786
+ Gio::SettingsBindFlags::DEFAULT)
787
+ end
788
+ end
789
+ ```
790
+
791
+ Nothing new here, it works like previously. The main difference in our application now is that we define what must be done when the *preferences* menu item is clicked.
792
+
793
+ ```ruby
794
+ action = Gio::SimpleAction.new("preferences")
795
+ action.signal_connect("activate") do |_action, _parameter|
796
+ win = application.windows.first
797
+
798
+ prefs = ExampleAppPrefs.new(:transient_for => win,
799
+ :use_header_bar => true)
800
+ prefs.present
801
+ end
802
+ ```
803
+ Here we just says that when the user activate the *preferences* item, we create an `ExampleAppPrefs` instance and display it. The user can then specify the *font* and *transition* settings for the application. Those settings are used in the `ExampleAppWindow#open` method for example:
804
+
805
+ ```ruby
806
+ def open(file)
807
+ basename = file.basename
808
+ scrolled = Gtk::ScrolledWindow.new
809
+ scrolled.show
810
+ scrolled.set_hexpand(true)
811
+ scrolled.set_vexpand(true)
812
+ view = Gtk::TextView.new
813
+ view.set_editable(false)
814
+ view.set_cursor_visible(false)
815
+ view.show
816
+ scrolled.add(view)
817
+ stack.add_titled(scrolled, basename, basename)
818
+ stream = file.read
819
+ buffer = view.buffer
820
+ buffer.text = stream.read
821
+ tag = buffer.create_tag()
822
+ @settings.bind("font", tag, "font", Gio::SettingsBindFlags::DEFAULT)
823
+ buffer.apply_tag(tag, buffer.start_iter, buffer.end_iter)
824
+ end
825
+ ```
826
+
827
+ ## Adding a search bar
828
+ https://developer.gnome.org/gtk3/stable/ch01s04.html#id-1.2.3.12.10
829
+
830
+ * exampleapp7/exampleapp.rb
831
+
832
+ We continue to flesh out the functionality of our application. For now, we add search. GTK+ supports this with `Gtk::SearchEntry` and `Gtk::SearchBar`. The search bar is a widget that can slide in from the top to present a search entry.
833
+ We add a toggle button to the header bar, which can be used to slide out the search bar below the header bar.
834
+
835
+ The new window.ui file:
836
+
837
+ ```xml
838
+ <?xml version="1.0" encoding="UTF-8"?>
839
+ <interface>
840
+ <!-- interface-requires gtk+ 3.8 -->
841
+ <template class="ExampleAppWindow" parent="GtkApplicationWindow">
842
+ <property name="title" translatable="yes">Example Application</property>
843
+ <property name="default-width">600</property>
844
+ <property name="default-height">400</property>
845
+ <child>
846
+ <object class="GtkBox" id="content_box">
847
+ <property name="visible">True</property>
848
+ <property name="orientation">vertical</property>
849
+ <child>
850
+ <object class="GtkHeaderBar" id="header">
851
+ <property name="visible">True</property>
852
+ <child type="title">
853
+ <object class="GtkStackSwitcher" id="tabs">
854
+ <property name="visible">True</property>
855
+ <property name="margin">6</property>
856
+ <property name="stack">stack</property>
857
+ </object>
858
+ </child>
859
+ <child>
860
+ <object class="GtkToggleButton" id="search">
861
+ <property name="visible">True</property>
862
+ <property name="sensitive">False</property>
863
+ <style>
864
+ <class name="image-button"/>
865
+ </style>
866
+ <child>
867
+ <object class="GtkImage" id="search-icon">
868
+ <property name="visible">True</property>
869
+ <property name="icon-name">edit-find-symbolic</property>
870
+ <property name="icon-size">1</property>
871
+ </object>
872
+ </child>
873
+ </object>
874
+ <packing>
875
+ <property name="pack-type">end</property>
876
+ </packing>
877
+ </child>
878
+ </object>
879
+ </child>
880
+ <child>
881
+ <object class="GtkSearchBar" id="searchbar">
882
+ <property name="visible">True</property>
883
+ <child>
884
+ <object class="GtkSearchEntry" id="searchentry">
885
+ <signal name="search-changed" handler="search_text_changed"/>
886
+ <property name="visible">True</property>
887
+ </object>
888
+ </child>
889
+ </object>
890
+ </child>
891
+ <child>
892
+ <object class="GtkStack" id="stack">
893
+ <signal name="notify::visible-child" handler="visible_child_changed"/>
894
+ <property name="visible">True</property>
895
+ </object>
896
+ </child>
897
+ </object>
898
+ </child>
899
+ </template>
900
+ </interface>
901
+ ```
902
+ Implementing the search needs quite a few code changes that we are not going to completely go over here. The central piece of the search implementation is a signal handler that listens for text changes in the search entry.
903
+
904
+ ```ruby
905
+
906
+ def init
907
+ set_template(:resource => "/org/gtk/exampleapp/window.ui")
908
+ bind_template_child("stack")
909
+ bind_template_child("search")
910
+ bind_template_child("searchbar")
911
+ set_connect_func do |name|
912
+ method(name)
913
+ end
914
+ end
915
+
916
+ private
917
+
918
+ def search_text_changed(search_entry)
919
+ text = search_entry.text
920
+ return if text.empty?
921
+
922
+ win = search_entry.toplevel
923
+ tab = win.stack.visible_child
924
+ view = tab.child
925
+ buffer = view.buffer
926
+ range = buffer.start_iter.forward_search(text, Gtk::TextSearchFlags::CASE_INSENSITIVE)
927
+ return unless range
928
+ buffer.select_range(range[0], range[1])
929
+ view.scroll_to_iter(range[0], 0.0, false, 0.0, 0.0)
930
+ end
931
+ ```
932
+
933
+ In this part of code, the use of the method `set_connect_func` will allow us to define private methods as callback that have been set in the handler attributs of the XML ui file. In the code above, we can see that we have defined a private method name `search_text_changed`. In the XML file, there is this line :
934
+
935
+ <signal name="search-changed" handler="search_text_changed"/>
936
+
937
+ Those pieces together mean that for the signal *search-changed* of the `Gtk::SearchEntry`, trigger the private method of `ExampleAppWindow` that is called `search_text_changed`.
938
+
@@ -63,4 +63,4 @@ require 'gtk3'
63
63
 
64
64
  Gtk.init
65
65
 
66
- exit Test::Unit::AutoRunner.run(true)
66
+ exit Test::Unit::AutoRunner.run(true, File.join(gtk3_base, "test"))
@@ -19,16 +19,18 @@ class TestGtkBuilder < Test::Unit::TestCase
19
19
  assert_kind_of(Gtk::Dialog, builder["dialog1"])
20
20
  end
21
21
 
22
+ test "path" do
23
+ only_gtk_version(3, 10, 0)
24
+ builder = Gtk::Builder.new(:path => ui_definition_file.path)
25
+ assert_kind_of(Gtk::Dialog, builder["dialog1"])
26
+ end
27
+
22
28
  test "resource" do
23
29
  only_gtk_version(3, 10, 0)
24
- resource = Gio::Resource.load(fixture_path("simple_window.gresource"))
25
- Gio::Resources.register(resource)
26
- begin
30
+ register_resource(fixture_path("simple_window.gresource")) do
27
31
  resource_path = "/simple_window/simple_window.ui"
28
32
  builder = Gtk::Builder.new(:resource => resource_path)
29
33
  assert_kind_of(Gtk::Window, builder["window"])
30
- ensure
31
- Gio::Resources.unregister(resource)
32
34
  end
33
35
  end
34
36
 
@@ -39,43 +41,109 @@ class TestGtkBuilder < Test::Unit::TestCase
39
41
  end
40
42
  end
41
43
 
42
- def test_add_from_file
43
- builder = Gtk::Builder.new
44
- assert_nothing_raised do
45
- builder.add_from_file(ui_definition_file.path)
44
+ sub_test_case "#add" do
45
+ sub_test_case ":file" do
46
+ test "all" do
47
+ builder = Gtk::Builder.new
48
+ builder.add(:file => ui_definition_file.path)
49
+ assert_kind_of(Gtk::Dialog, builder["dialog1"])
50
+ end
51
+
52
+ test ":object_ids" do
53
+ builder = Gtk::Builder.new
54
+ builder.add(:file => ui_definition_file.path,
55
+ :object_ids => ["ok_button"])
56
+ assert_equal(["ok_button"],
57
+ builder.objects.collect(&:builder_name).sort)
58
+ end
59
+ end
60
+
61
+ sub_test_case ":path" do
62
+ test "all" do
63
+ builder = Gtk::Builder.new
64
+ builder.add(:path => ui_definition_file.path)
65
+ assert_kind_of(Gtk::Dialog, builder["dialog1"])
66
+ end
67
+
68
+ test ":object_ids" do
69
+ builder = Gtk::Builder.new
70
+ builder.add(:path => ui_definition_file.path,
71
+ :object_ids => ["ok_button"])
72
+ assert_equal(["ok_button"],
73
+ builder.objects.collect(&:builder_name).sort)
74
+ end
46
75
  end
47
- assert_kind_of(Gtk::Dialog, builder["dialog1"])
48
- end
49
76
 
50
- sub_test_case "#add_from_string" do
51
- def test_ascii_only
77
+ test "path" do
52
78
  builder = Gtk::Builder.new
53
- builder.add_from_string(ui_definition_simple)
54
- assert_kind_of(Gtk::Window, builder["main-window"])
79
+ builder.add(ui_definition_file.path)
80
+ assert_kind_of(Gtk::ButtonBox, builder["hbuttonbox1"])
55
81
  end
56
82
 
57
- def test_multibyte_characters
83
+ sub_test_case ":resource" do
84
+ setup do
85
+ only_gtk_version(3, 12, 0)
86
+ end
87
+
88
+ test "all" do
89
+ builder = Gtk::Builder.new
90
+ register_resource(fixture_path("simple_window.gresource")) do
91
+ resource_path = "/simple_window/simple_window.ui"
92
+ builder.add(:resource => resource_path)
93
+ assert_kind_of(Gtk::Window, builder["window"])
94
+ end
95
+ end
96
+
97
+ test ":object_ids" do
98
+ builder = Gtk::Builder.new
99
+ register_resource(fixture_path("simple_window.gresource")) do
100
+ resource_path = "/simple_window/simple_window.ui"
101
+ builder.add(:resource => resource_path,
102
+ :object_ids => ["label"])
103
+ assert_equal(["label"],
104
+ builder.objects.collect(&:builder_name).sort)
105
+ end
106
+ end
107
+ end
108
+
109
+ test "resource" do
110
+ only_gtk_version(3, 12, 0)
58
111
  builder = Gtk::Builder.new
59
- comment = "<!-- 日本語 -->\n" * 100
60
- builder.add_from_string("#{comment}#{ui_definition_simple}")
61
- assert_kind_of(Gtk::Window, builder["main-window"])
112
+ register_resource(fixture_path("simple_window.gresource")) do
113
+ resource_path = "/simple_window/simple_window.ui"
114
+ builder.add(resource_path)
115
+ assert_kind_of(Gtk::Window, builder["window"])
116
+ end
62
117
  end
63
- end
64
118
 
65
- def test_add_with_file
66
- builder = Gtk::Builder.new
67
- assert_nothing_raised do
68
- builder.add(ui_definition_file.path)
119
+ sub_test_case ":string" do
120
+ test "ascii only" do
121
+ builder = Gtk::Builder.new
122
+ builder.add(:string => ui_definition_simple)
123
+ assert_kind_of(Gtk::Window, builder["main-window"])
124
+ end
125
+
126
+ test "multibyte characters" do
127
+ builder = Gtk::Builder.new
128
+ comment = "<!-- 日本語 -->\n" * 100
129
+ builder.add(:string => "#{comment}#{ui_definition_simple}")
130
+ assert_kind_of(Gtk::Window, builder["main-window"])
131
+ end
132
+
133
+ test ":object_ids" do
134
+ builder = Gtk::Builder.new
135
+ builder.add(:string => ui_definition,
136
+ :object_ids => ["ok_button"])
137
+ assert_equal(["ok_button"],
138
+ builder.objects.collect(&:builder_name).sort)
139
+ end
69
140
  end
70
- assert_kind_of(Gtk::ButtonBox, builder["hbuttonbox1"])
71
- end
72
141
 
73
- def test_add_with_string
74
- builder = Gtk::Builder.new
75
- assert_nothing_raised do
142
+ test "string" do
143
+ builder = Gtk::Builder.new
76
144
  builder.add(ui_definition)
145
+ assert_kind_of(Gtk::Button, builder["ok_button"])
77
146
  end
78
- assert_kind_of(Gtk::Button, builder["ok_button"])
79
147
  end
80
148
 
81
149
  def test_add_chain
@@ -197,4 +265,14 @@ EOX
197
265
  xml.close
198
266
  xml
199
267
  end
268
+
269
+ def register_resource(path)
270
+ resource = Gio::Resource.load(path)
271
+ Gio::Resources.register(resource)
272
+ begin
273
+ yield
274
+ ensure
275
+ Gio::Resources.unregister(resource)
276
+ end
277
+ end
200
278
  end