├── .gitattributes ├── .gitignore ├── .gyro └── redirects ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md ├── STATUS.md ├── build.zig ├── examples ├── callbacks.zig ├── example.glade ├── glade.zig ├── range.zig └── simple.zig ├── lib.zig ├── src ├── accelgroup.zig ├── actionable.zig ├── actionbar.zig ├── adjustment.zig ├── appchooser.zig ├── bin.zig ├── box.zig ├── buildable.zig ├── builder.zig ├── button.zig ├── buttonbox.zig ├── cimport.zig ├── colorchooser.zig ├── combobox.zig ├── common.zig ├── container.zig ├── convenience.zig ├── dialog.zig ├── entry.zig ├── enums.zig ├── expander.zig ├── filechooser.zig ├── filefilter.zig ├── fixed.zig ├── flowbox.zig ├── fontchooser.zig ├── frame.zig ├── grid.zig ├── gtk.zig ├── headerbar.zig ├── image.zig ├── invisible.zig ├── label.zig ├── layout.zig ├── menu.zig ├── notebook.zig ├── orientable.zig ├── paned.zig ├── popover.zig ├── range.zig ├── revealer.zig ├── scrollable.zig ├── separator.zig ├── spinner.zig ├── stack.zig ├── switch.zig ├── widget.zig └── window.zig └── zigmod.yml /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | *.zig text eol=lf 3 | zigmod.* text eol=lf 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | zig-out/ 2 | zig-cache/ 3 | docs/ 4 | *.glade~ 5 | *.a 6 | gyro.lock 7 | deps.zig 8 | .gyro 9 | .zigmod 10 | deps.zig 11 | tags 12 | -------------------------------------------------------------------------------- /.gyro/redirects: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nfisher1226/zig-gtk3/da5042dd2b0b4e19d25c6143c369be4a0a3eda23/.gyro/redirects -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | Contents 3 | ======== 4 | * [Wrapping a Gtk+ class](#wrapping-a-gtk+-class) 5 | * [Naming](#naming) 6 | * [Required functions](#required-functions) 7 | * [Dealing with strings](#dealing-with-strings) 8 | * [Dealing with NULL](#dealing-with-null) 9 | * [Dealing with gboolean](#dealing-with-gboolean) 10 | * [Dealing with enums](#dealing-with-enums) 11 | * [Connecting signals](#connecting-signals) 12 | * [Finishing up](#finishing-up) 13 | 14 | ## Wrapping a Gtk+ class 15 | Each Gtk+ class, or widget, will have a corresponding Zig struct as a container 16 | type. The only field in this struct will be `ptr`, which is as you probably 17 | guessed the C style pointer to that object. This allows us to have proper 18 | namespacing in our bindings and use method call syntax on the functions 19 | associated with that class. 20 | 21 | ## Required functions 22 | Assuming a hypothetical Gtk+ class `GtkMine`.. 23 | ```Zig 24 | pub fn is_instance(gtype: u64) bool { 25 | return (gtype == c.gtk_mine_get_type()); 26 | } 27 | ``` 28 | The `is_instance` function just returns whether or not something is of this type. 29 | For the curious, this function is called when attempting to cast from a `Widget` 30 | base type to our class, using the highly generic function `isa` associated with 31 | the `Widget` struct. 32 | ```Zig 33 | pub fn as_widget(self: Self) Widget { 34 | return Widget{ 35 | .ptr = @ptrCast(*c.GtkWidget, self.ptr), 36 | }; 37 | } 38 | ``` 39 | The `as_widget` function allows casting our class to the `Widget` base class, 40 | giving us access to all of the functions associated with that type. In addition 41 | to the `Widget` class, our class will have one or more other parent classes that 42 | it inherits from, such as `Box` or `Container`. For each parent class there should 43 | be a corresponding `as_` function returning the parent type by returning it's 44 | container struct with the `ptr` field being our `ptr` casted to the corresponding 45 | Gtk+ pointer type. 46 | 47 | > Note: `Self` here is usable because we've declared `const Self = @This()` inside 48 | > our struct definition. You should follow suit. 49 | 50 | ## Dealing with strings 51 | We're currently using a non-optimal approach to interacting with **C** strings 52 | in that they get re-allocated into a **Zig**-freindly `[:0]const u8`, giving us 53 | access to all of the awesome string manipulation and formatting features in 54 | `std.mem` and `std.fmt`. This is actually quite common for a language binding to 55 | a **C** library to re-allocate strings at the language barrier, and is done in 56 | some other languages `Gtk+` bindings actually. 57 | 58 | If a user wishes to squeeze every last drop of performance out of their application, 59 | then this additional memory overhead might be undesireable. The beauty of 60 | interacting with **C** libraries via **Zig** is that we always have the option of 61 | falling back to using the **C** api directly. We can even do things like call 62 | `strncat` or `strndup` from `libc`. 63 | 64 | For the purposes of our bindings, however, any time we are translating a function 65 | which returns a **C** string, we need to pass it an allocator and move it into 66 | **Zig** properly. Here's an example from the `Headerbar` widget. 67 | ```Zig 68 | pub fn get_title(self: Self, allocator: mem.Allocator) ?[:0]const u8 { 69 | const val = c.gtk_header_bar_get_title(self.ptr); 70 | const len = mem.len(val); 71 | return fmt.allocPrintZ(allocator, "{s}", .{val[0..len]}) catch return null; 72 | } 73 | ``` 74 | Passing strings into **C** functions is simpler, as the compiler can coerce the 75 | array into the proper type for us. 76 | ```Zig 77 | pub fn set_title(self: Self, title: [:0]const u8) void { 78 | c.gtk_header_bar_set_title(self.ptr, title); 79 | } 80 | ``` 81 | In either event, do *not* forget the null termination. 82 | 83 | ## Dealing with NULL 84 | When reading the `gtk` api docs, you will often come across a function that might 85 | return a value or `NULL`. A good example would be the `gtk_paned_get_child1` 86 | function: 87 | ```C 88 | GtkWidget * 89 | gtk_paned_get_child1 (GtkPaned *paned); 90 | ``` 91 | If we look under the definition, to the **Returns** section, it reads: 92 | **Returns** 93 | first child, or NULL if it is not set. 94 | 95 | Here's our wrapper function, using proper `null` ettiquette in **Zig**: 96 | ```Zig 97 | pub fn get_child1(self: Self) ?Widget { 98 | return if (c.gtk_paned_get_child1(self.ptr)) |child| Widget{ 99 | .ptr = child, 100 | } else null; 101 | } 102 | ``` 103 | We're basically translating the concept of a pointer which might point to address 104 | `0` in **C** to the concept of a **Zig** `optional`. Note that when going the 105 | other way we have to do the same thing, if a **C** function takes a parameter *or* 106 | `null`. 107 | ```Zig 108 | // from widget.zig 109 | pub fn connect(self: Self, sig: [:0]const u8, callback: c.GCallback, data: ?c.gpointer) void { 110 | _ = signal_connect(self.ptr, sig, callback, if (data) |d| d else null); 111 | } 112 | ``` 113 | 114 | ## Dealing with gboolean 115 | A `gboolean` in Gtk+ is nothing more than a `c_int` having a value of `1` 116 | corresponding to `true` and `0` corresponding to `false`. **Zig** has an actual 117 | `bool` type, and we want to be able to pass that to our wrapped functions and 118 | get a true `bool` as a return value. This is quite easy once you wrap your head 119 | around it, but should be mostly hidden from the user of the library. 120 | ```Zig 121 | // stack.zig 122 | pub fn set_homogeneous(self: Self, hom: bool) void { 123 | c.gtk_stack_set_homogeneous(self.ptr, if (hom) 1 else 0); 124 | } 125 | 126 | pub fn get_homogeneous(self: Self) bool { 127 | return (c.gtk_stack_get_homeogeneous(self.ptr) == 1); 128 | } 129 | ``` 130 | 131 | ## Dealing with enums 132 | 133 | ## Connecting signals 134 | 135 | ## Finishing up 136 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | ## The MIT License (MIT) 2 | Copyright © 2021 Nathan Fisher 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # zig-gtk3 2 | This package contains some convenience functions and wrappers around the C api 3 | of both the Gtk+ and Vte libraries for developing Gui applications using Zig. 4 | 5 | ## Usage 6 | We track zig-master, so you will need the current master compiler. In your 7 | ```build.zig``` file, add the package path: 8 | ```Zig 9 | const exe = b.addExecutable("exe-name", "path-to-source.zig"); 10 | exe.addPackagePath("zig-gtk3", "path/to/zig-gtk3/lib.zig"); 11 | exe.linkLibC(); 12 | exe.linkSystemLibrary("gtk+-3.0"); 13 | ``` 14 | The Gtk wrappers are namespaced to gtk, and the C functions to c. 15 | ```Zig 16 | const GTK @import("zig-gtk3"); 17 | const c = GTK.c; 18 | const gtk = GTK.gtk; 19 | const std = @import("std"); 20 | 21 | const Gui = struct { 22 | window: gtk.Window, 23 | 24 | fn init(app: *c.GtkApplication) Gui { 25 | ... 26 | ``` 27 | There are a number of examples in the "examples" subdirectory which can be built 28 | with by running `zig build` in this directory. 29 | 30 | ## Rationale 31 | It is entirely possible to call C functions directly from Zig. However, Zig's 32 | translate-c function, which is used to import C code into Zig, is still somewhat 33 | immature and tends to fail with heavily macro dependent code. This happens for 34 | certain parts of Gtk+ that make working around it quite difficult. 35 | 36 | Additionally, the C Api to Gtk (and Vte), due to limitations of the language, can 37 | be incredibly verbose as well as quite clumsy at times. A better Api is both 38 | possible and desireable in a language such as Zig. 39 | -------------------------------------------------------------------------------- /STATUS.md: -------------------------------------------------------------------------------- 1 | | Gtk+ class | Not Started | Begun | Complete | 2 | | ---------- | ----------- | ----- | -------- | 3 | | GtkApplication | | x | | 4 | | GtkApplicationWindow | | x | | 5 | | GtkActionable | | |x | 6 | | GtkBuilder | | x | | 7 | | GtkBuildable | | x | | 8 | | GtkWindow | | x | | 9 | | GtkDialog | | x | | 10 | | GtkMessageDialog | | | x | 11 | | GtkAboutDialog | | | x | 12 | | GtkAssistant | x | | | 13 | | GtkInvisible | | | x | 14 | | GtkOffscreenWindow | x | | | 15 | | GtkWindowGroup | x | | | 16 | | GtkBox | | | x | 17 | | GtkGrid | | | x | 18 | | GtkRevealer | | | x | 19 | | GtkListBox | x | | | 20 | | GtkFlowBox | | | x | 21 | | GtkStack | | | x | 22 | | GtkStackSwitcher | | | x | 23 | | GtkStackSidebar | | | x | 24 | | GtkActionBar | | | x | 25 | | GtkHeaderBar | | | x | 26 | | GtkOverlay | x | | | 27 | | GtkButtonBox | | | x | 28 | | GtkPaned | | | x | 29 | | GtkLayout | | | x | 30 | | GtkNotebook | | | x | 31 | | GtkExpander | | x | | 32 | | GtkOrientable | | x | | 33 | | GtkAspectFrame | | | x | 34 | | GtkFixed | | | x | 35 | | GtkLabel | | | x | 36 | | GtkImage | | | x | 37 | | GtkSpinner | | | x | 38 | | GtkInfoBar | x | | | 39 | | GtkProgressBar | x | | | 40 | | GtkLevelBar | x | | | 41 | | GtkStatusBar | x | | | 42 | | GtkAccelLabel | | | x | 43 | | GtkButton | | | x | 44 | | GtkCheckButton | | | x | 45 | | GtkRadioButton | x | | | 46 | | GtkToggleButton | | | x | 47 | | GtkLinkButton | x | | | 48 | | GtkMenuButton | x | | | 49 | | GtkSwitch | | | x | 50 | | GtkScaleButton | x | | | 51 | | GtkVolumeButton | x | | | 52 | | GtkLockButton | x | | | 53 | | GtkModalButton | x | | | 54 | | GtkEntry | | x | | 55 | | GtkEntryBuffer | | x | | 56 | | GtkEntryCompletion | x | | | 57 | | GtkScale | | | x | 58 | | GtkSpinButton | | | x | 59 | | GtkSearchEntry | x | | | 60 | | GtkSearchBar | x | | | 61 | | GtkEditable | x | | | 62 | | GtkTextIter | x | | | 63 | | GtkTextMark | x | | | 64 | | GtkTextBuffer | x | | | 65 | | GtkTextTag | x | | | 66 | | GtkTextTagTable | x | | | 67 | | GtkTextView | x | | | 68 | | GtkTreeModel | x | | | 69 | | GtkTreeSelection | x | | | 70 | | GtkTreeViewColumn | x | | | 71 | | GtkTreeView | x | | | 72 | | GtkCellView | x | | | 73 | | GtkIconView | x | | | 74 | | GtkTreeSortable | x | | | 75 | | GtkTreeModelSort | x | | | 76 | | GtkTreeModelFilter | x | | | 77 | | GtkCellLayout | | | x | 78 | | GtkcellArea | x | | | 79 | | GtkCellAreaBox | x | | | 80 | | GtkcellAreaContext | x | | | 81 | | GtkCellRenderer | x | | | 82 | | GtkCellEditable | x | | | 83 | | GtkCellRendererAccel | x | | | 84 | | GtkCellRendererComobo | x | | | 85 | | GtkCellRendererPixbuf | x | | | 86 | | GtkCellRendererProgress | x | | | 87 | | GtkCellRendererSpin | x | | | 88 | | GtkCellRendererText | x | | | 89 | | GtkCellRendererToggle | x | | | 90 | | GtkCellRendererSpinner | x | | | 91 | | GtkListStore | x | | | 92 | | GtkTreeStore | x | | | 93 | | GtkComboBox | | | x | 94 | | GtkComboBoxText | | | x | 95 | | GtkMenu | | x | | 96 | | GtkMenuBar | x | | | 97 | | GtkMenuItem | | x | | 98 | | GtkRadioMenuItem | x | | | 99 | | GtkCheckMenuItem | x | | | 100 | | GtkseparatorMenuItem | x | | | 101 | | GtkToolShell | x | | | 102 | | GtkToolBar | x | | | 103 | | GtkToolItem | x | | | 104 | | GtkToolPalette | x | | | 105 | | GtkToolItemGroup | x | | | 106 | | GtkSeparatorToolItem | x | | | 107 | | GtkToolButton | x | | | 108 | | GtkMenuToolButton | x | | | 109 | | GtkToggleToolButton | x | | | 110 | | GtkRadioToolButton | x | | | 111 | | GtkPopover | | | x | 112 | | GtkPopoverMenu | | | x | 113 | | GtkColorChooser | | x | | 114 | | GtkColorButton | | x | | 115 | | GtkColorChooserWidget | | x | | 116 | | GtkColorChooserDialog | | x | | 117 | | GtkFileChooser | x | | | 118 | | GtkFileChooserButton | | | x | 119 | | GtkFileChooserNative | | | x | 120 | | GtkFileChooserDialog | | | x | 121 | | GtkFileChooserWidget | | | x | 122 | | GtkFileFilter | | | x | 123 | | GtkFontChooser | | | x | 124 | | GtkFontButton | | | x | 125 | | GtkFontChooserWidget | | | x | 126 | | GtkFontChooserDialog | | | x | 127 | | GtkPlacesSidebar | | | x | 128 | | GtkFrame | | | x | 129 | | GtkSeparator | | | x | 130 | | GtkScollbar | x | | | 131 | | GtkScrolledWindow | x | | | 132 | | GtkScrollable | | | x | 133 | | GtkPrintOperation | x | | | 134 | | GtkPrintContext | x | | | 135 | | GtkPrintSettings | x | | | 136 | | GtkPageSetup | x | | | 137 | | GtkPaperSize | x | | | 138 | | GtkPrinter | x | | | 139 | | GtkPrintJob | x | | | 140 | | GtkPrintUnixDialog | x | | | 141 | | GtkPageSetupUnixDialog | x | | | 142 | | GtkShortcutsWindow | x | | | 143 | | GtkShortcutsSection | x | | | 144 | | GtkShortcutsGroup | x | | | 145 | | GtkShortcutsShortcut | x | | | 146 | | GtkAdjustment | | | x | 147 | | GtkCalendar | x | | | 148 | | GtkDrawingArea | x | | | 149 | | GtkGlArea | x | | | 150 | | GtkEventBox | x | | | 151 | | GtkHandleBox | x | | | 152 | | GtkIMContextSimple | x | | | 153 | | GtkIMMulticontext | x | | | 154 | | GtkSizeGroup | x | | | 155 | | GtkTooltip | x | | | 156 | | Gtkviewport | x | | | 157 | | GtkAccessible | x | | | 158 | | GtkWidget | | | x | 159 | | GtkContainer | | | x | 160 | | GtkBin | | | x | 161 | | GtkMenuShell | x | | | 162 | | GtkRange | | | x | 163 | | GtkIMContext | x | | | 164 | | GtkNativeDialog | x | | | 165 | | GtkPLug | x | | | 166 | | GtkSocket | x | | | 167 | | GtkRecentManager | x | | | 168 | | GtkRecentChooser | x | | | 169 | | GtkRecentChooserDialog | x | | | 170 | | GtkRecentChooserMenu | x | | | 171 | | GtkRecentChooserWidget | x | | | 172 | | GtkRecentFilter | x | | | 173 | | GtkAppChooser | | |x | 174 | | GtkAppChooserButton | | | x | 175 | | GtkAppChooserDialog | | | x | 176 | | GtkAppChooserWidget | | | x | 177 | -------------------------------------------------------------------------------- /build.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | 3 | const Builder = std.build.Builder; 4 | 5 | pub fn build(b: *Builder) void { 6 | const target = b.standardTargetOptions(.{}); 7 | const mode = b.standardReleaseOptions(); 8 | const examples = .{ "simple", "glade", "callbacks", "range" }; 9 | 10 | const lib = b.addStaticLibrary("zig-gtk3", "lib.zig"); 11 | lib.setBuildMode(mode); 12 | lib.install(); 13 | 14 | const example_step = b.step("examples", "Build examples"); 15 | inline for (examples) |name| { 16 | const example = b.addExecutable(name, "examples/" ++ name ++ ".zig"); 17 | example.addPackagePath("gtk", "lib.zig"); 18 | example.setBuildMode(mode); 19 | example.setTarget(target); 20 | example.linkLibC(); 21 | example.linkSystemLibrary("gtk+-3.0"); 22 | example.install(); 23 | example_step.dependOn(&example.step); 24 | } 25 | 26 | const all_step = b.step("all", "Build everything"); 27 | all_step.dependOn(example_step); 28 | b.default_step.dependOn(all_step); 29 | } 30 | -------------------------------------------------------------------------------- /examples/callbacks.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const GTK = @import("gtk"); 3 | const c = GTK.c; 4 | const gtk = GTK.gtk; 5 | const allocator = std.heap.page_allocator; 6 | const fmt = std.fmt; 7 | const mem = std.mem; 8 | 9 | var widgets: Widgets = undefined; 10 | 11 | const Widgets = struct { 12 | window: gtk.ApplicationWindow, 13 | label: gtk.Label, 14 | button: gtk.Button, 15 | 16 | fn init(app: *c.GtkApplication) Widgets { 17 | return Widgets{ 18 | .window = gtk.ApplicationWindow.new(app), 19 | .label = gtk.Label.new("Off"), 20 | .button = gtk.Button.new_with_label("Click Me"), 21 | }; 22 | } 23 | 24 | fn toggle_label(self: Widgets) void { 25 | const text = self.label.get_text(allocator); 26 | if (text) |t| { 27 | defer allocator.free(t); 28 | if (mem.eql(u8, t, "On")) { 29 | self.label.set_text("Off"); 30 | } else { 31 | self.label.set_text("On"); 32 | } 33 | } 34 | } 35 | 36 | fn connect_signals(self: Widgets) void { 37 | self.button.connect_clicked(@ptrCast(c.GCallback, &button_callback), null); 38 | } 39 | }; 40 | 41 | pub fn main() !void { 42 | const app = c.gtk_application_new("org.gtk.example", c.G_APPLICATION_FLAGS_NONE) orelse @panic("null app :("); 43 | defer c.g_object_unref(app); 44 | 45 | _ = c.g_signal_connect_data( 46 | app, 47 | "activate", 48 | @ptrCast(c.GCallback, &activate), 49 | null, 50 | null, 51 | c.G_CONNECT_AFTER, 52 | ); 53 | _ = c.g_application_run(@ptrCast(*c.GApplication, app), 0, null); 54 | } 55 | 56 | fn activate(app: *c.GtkApplication) void { 57 | widgets = Widgets.init(app); 58 | widgets.connect_signals(); 59 | const box = gtk.Box.new(gtk.Orientation.vertical, 5); 60 | const window = widgets.window.as_window(); 61 | box.pack_start(widgets.label.as_widget(), false, true, 1); 62 | box.pack_start(widgets.button.as_widget(), false, true, 1); 63 | widgets.window.as_container().add(box.as_widget()); 64 | window.set_title("Callbacks Example"); 65 | window.set_default_size(400, -1); 66 | widgets.window.as_widget().show_all(); 67 | } 68 | 69 | fn button_callback() void { 70 | widgets.toggle_label(); 71 | } 72 | -------------------------------------------------------------------------------- /examples/example.glade: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | False 7 | 8 | 9 | True 10 | False 11 | vertical 12 | 13 | 14 | True 15 | False 16 | Glade Example 17 | True 18 | 19 | 20 | True 21 | True 22 | False 23 | True 24 | 25 | 26 | True 27 | False 28 | gtk-justify-fill 29 | 30 | 31 | 32 | 33 | 34 | 35 | False 36 | True 37 | 0 38 | 39 | 40 | 41 | 42 | True 43 | False 44 | 10 45 | 5 46 | <b><big>Hello World!</big></b> 47 | True 48 | 49 | 50 | False 51 | True 52 | 1 53 | 54 | 55 | 56 | 57 | True 58 | False 59 | 5 60 | 10 61 | All your interfaces are belong to us. 62 | 63 | 64 | False 65 | True 66 | 2 67 | 68 | 69 | 70 | 71 | True 72 | False 73 | 74 | 75 | True 76 | False 77 | start 78 | 79 | 80 | gtk-ok 81 | True 82 | True 83 | True 84 | True 85 | 86 | 87 | True 88 | True 89 | 0 90 | 91 | 92 | 93 | 94 | gtk-cancel 95 | True 96 | True 97 | True 98 | True 99 | 100 | 101 | True 102 | True 103 | 1 104 | 105 | 106 | 107 | 108 | False 109 | True 110 | end 111 | 0 112 | 113 | 114 | 115 | 116 | False 117 | True 118 | 3 119 | 120 | 121 | 122 | 123 | 124 | 125 | -------------------------------------------------------------------------------- /examples/glade.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const GTK = @import("gtk"); 3 | const c = GTK.c; 4 | const gtk = GTK.gtk; 5 | 6 | pub fn main() !void { 7 | const app = c.gtk_application_new("org.gtk.example", c.G_APPLICATION_FLAGS_NONE) orelse @panic("null app :("); 8 | defer c.g_object_unref(app); 9 | 10 | _ = c.g_signal_connect_data( 11 | app, 12 | "activate", 13 | @ptrCast(c.GCallback, &activate), 14 | null, 15 | null, 16 | c.G_CONNECT_AFTER, 17 | ); 18 | _ = c.g_application_run(@ptrCast(*c.GApplication, app), 0, null); 19 | } 20 | 21 | fn activate(app: *c.GtkApplication) void { 22 | const builder = gtk.Builder.new(); 23 | builder.add_from_string(@embedFile("example.glade")) catch |e| { 24 | std.debug.print("{}\n", .{e}); 25 | return; 26 | }; 27 | builder.set_application(app); 28 | // Builder.get_widget() returns an optional, so unwrap if there is a value 29 | if (builder.get_widget("window")) |w| { 30 | w.show_all(); 31 | w.connect("delete-event", @ptrCast(c.GCallback, &c.gtk_main_quit), null); 32 | // Widget.to_[otherwidget]() functions return an optional, as we're going to check 33 | // whether it's a valid instance before returning 34 | if (w.to_window()) |window| { 35 | window.set_decorated(false); 36 | } 37 | } 38 | if (builder.get_widget("ok_button")) |w| { 39 | if (w.to_button()) |b| { 40 | b.connect_clicked(@ptrCast(c.GCallback, &c.gtk_main_quit), null); 41 | } 42 | } 43 | if (builder.get_widget("cancel_button")) |w| { 44 | if (w.to_button()) |b| { 45 | b.connect_clicked(@ptrCast(c.GCallback, &c.gtk_main_quit), null); 46 | } 47 | } 48 | 49 | c.gtk_main(); 50 | } 51 | -------------------------------------------------------------------------------- /examples/range.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const allocator = std.heap.page_allocator; 3 | const fmt = std.fmt; 4 | const GTK = @import("gtk"); 5 | const gtk = GTK.gtk; 6 | const c = GTK.c; 7 | 8 | var scale0: gtk.Scale = undefined; 9 | var scale1: gtk.Scale = undefined; 10 | 11 | pub fn main() !void { 12 | const app = c.gtk_application_new("org.gtk.range-example", c.G_APPLICATION_FLAGS_NONE) orelse @panic("null app :("); 13 | defer c.g_object_unref(app); 14 | 15 | // Call the C function directly to connect our "activate" signal 16 | _ = c.g_signal_connect_data( 17 | app, 18 | "activate", 19 | @ptrCast(c.GCallback, &activate), 20 | null, 21 | null, 22 | c.G_CONNECT_AFTER, 23 | ); 24 | _ = c.g_application_run(@ptrCast(*c.GApplication, app), 0, null); 25 | } 26 | 27 | // Whatever we connect to the "activate" signal in main() actually builds and runs our application window 28 | fn activate(app: *c.GtkApplication) void { 29 | // Create an ApplicationWindow using our *GtkApplication pointer, which we then use as a window 30 | // in order to inherit the Window methods 31 | const window = gtk.ApplicationWindow.new(app).as_window(); 32 | window.set_title("Range Program"); 33 | window.set_default_size(400, 400); 34 | window.as_container().set_border_width(10); 35 | 36 | const vbox = gtk.Box.new(.vertical, 5); 37 | 38 | const heading0 = gtk.Label.new(null); 39 | heading0.set_markup("Linked Range widgets"); 40 | vbox.pack_start(heading0.as_widget(), false, true, 1); 41 | 42 | const text0 = gtk.Label.new("These two range widgets have been given the same Adjustment"); 43 | text0.set_line_wrap(true); 44 | vbox.pack_start(text0.as_widget(), false, true, 1); 45 | 46 | const scale_adjustment = gtk.Adjustment.new(0.0, 0.0, 100.0, 0.01, 10.0, 20.0); 47 | scale0 = gtk.Scale.new(.horizontal, scale_adjustment); 48 | 49 | const spinbutton = gtk.SpinButton.new(scale_adjustment, 10.0, 2); 50 | 51 | const hbox0 = gtk.Box.new(.horizontal, 2); 52 | hbox0.pack_start(scale0.as_widget(), true, true, 1); 53 | hbox0.pack_start(spinbutton.as_widget(), false, true, 1); 54 | vbox.pack_start(hbox0.as_widget(), false, true, 1); 55 | 56 | const heading1 = gtk.Label.new(null); 57 | heading1.set_markup("Orientation and Marks"); 58 | vbox.pack_start(heading1.as_widget(), false, true, 1); 59 | 60 | const text1_value = 61 | \\This scale can change orientation, and can have marks set 62 | \\and removed. Use the buttons below to explore these features. 63 | ; 64 | const text1 = gtk.Label.new(text1_value); 65 | vbox.pack_start(text1.as_widget(), false, true, 1); 66 | 67 | scale1 = gtk.Scale.new_with_range(.vertical, 0.0, 100.0, 10.0); 68 | vbox.pack_start(scale1.as_widget(), true, true, 1); 69 | 70 | const or_button = gtk.Button.new_with_label("Change orientation"); 71 | or_button.set_focus_on_click(false); 72 | or_button.connect_clicked(@ptrCast(c.GCallback, &change_orientation), null); 73 | 74 | const mark_button = gtk.Button.new_with_label("Set Mark"); 75 | mark_button.set_focus_on_click(false); 76 | mark_button.connect_clicked(@ptrCast(c.GCallback, &add_mark), null); 77 | 78 | const clr_button = gtk.Button.new_with_label("Clear Marks"); 79 | clr_button.set_focus_on_click(false); 80 | clr_button.connect_clicked(@ptrCast(c.GCallback, &clear_marks), null); 81 | 82 | const hbox1 = gtk.Box.new(.horizontal, 2); 83 | hbox1.pack_end(clr_button.as_widget(), false, true, 1); 84 | hbox1.pack_end(mark_button.as_widget(), false, true, 1); 85 | hbox1.pack_end(or_button.as_widget(), false, true, 1); 86 | vbox.pack_start(hbox1.as_widget(), false, true, 1); 87 | 88 | window.as_container().add(vbox.as_widget()); 89 | // show_all() is a Widget method 90 | window.as_widget().show_all(); 91 | } 92 | 93 | fn change_orientation() void { 94 | const orientable = scale1.as_orientable(); 95 | const orientation = orientable.get_orientation(); 96 | switch (orientation) { 97 | .horizontal => { 98 | orientable.set_orientation(.vertical); 99 | scale1.set_value_pos(.top); 100 | }, 101 | .vertical => { 102 | orientable.set_orientation(.horizontal); 103 | scale1.set_value_pos(.left); 104 | }, 105 | } 106 | } 107 | 108 | fn add_mark() void { 109 | const val = scale1.as_range().get_value(); 110 | const text = fmt.allocPrintZ(allocator, "{d}", .{val}) catch return; 111 | defer allocator.free(text); 112 | scale1.add_mark(val, .top, text); 113 | } 114 | 115 | fn clear_marks() void { 116 | scale1.clear_marks(); 117 | } 118 | -------------------------------------------------------------------------------- /examples/simple.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const GTK = @import("gtk"); 3 | const c = GTK.c; 4 | const gtk = GTK.gtk; 5 | 6 | pub fn main() !void { 7 | const app = c.gtk_application_new("org.gtk.example", c.G_APPLICATION_FLAGS_NONE) orelse @panic("null app :("); 8 | defer c.g_object_unref(app); 9 | 10 | // Call the C function directly to connect our "activate" signal 11 | _ = c.g_signal_connect_data( 12 | app, 13 | "activate", 14 | @ptrCast(c.GCallback, &activate), 15 | null, 16 | null, 17 | c.G_CONNECT_AFTER, 18 | ); 19 | _ = c.g_application_run(@ptrCast(*c.GApplication, app), 0, null); 20 | } 21 | 22 | // Whatever we connect to the "activate" signal in main() actually builds and runs our application window 23 | fn activate(app: *c.GtkApplication) void { 24 | // Create an ApplicationWindow using our *GtkApplication pointer, which we then use as a window 25 | // in order to inherit the Window methods 26 | const window = gtk.ApplicationWindow.new(app).as_window(); 27 | window.set_title("Example Program"); 28 | window.set_default_size(400, 400); 29 | // show_all() is a Widget method 30 | window.as_widget().show_all(); 31 | } 32 | -------------------------------------------------------------------------------- /lib.zig: -------------------------------------------------------------------------------- 1 | /// C functions 2 | pub const c = @import("src/cimport.zig"); 3 | /// Gtk+ wrappers 4 | pub const gtk = @import("src/gtk.zig"); 5 | -------------------------------------------------------------------------------- /src/accelgroup.zig: -------------------------------------------------------------------------------- 1 | const c = @import("cimport.zig"); 2 | 3 | /// Accelerator flags used with gtk_accel_group_connect(). 4 | pub const AccelFlags = enum(c_uint) { 5 | visible = c.GTK_ACCEL_VISIBLE, 6 | locked = c.GTK_ACCEL_LOCKED, 7 | mask = c.GTK_ACCEL_LOCKED, 8 | }; 9 | 10 | /// A GtkAccelGroup represents a group of keyboard accelerators, typically 11 | /// attached to a toplevel GtkWindow (with gtk_window_add_accel_group()). 12 | /// Usually you won’t need to create a GtkAccelGroup directly; instead, when 13 | /// using GtkUIManager, GTK+ automatically sets up the accelerators for your 14 | /// menus in the ui manager’s GtkAccelGroup. 15 | /// 16 | /// Note that “accelerators” are different from “mnemonics”. Accelerators are 17 | /// shortcuts for activating a menu item; they appear alongside the menu item 18 | /// they’re a shortcut for. For example “Ctrl+Q” might appear alongside the 19 | /// “Quit” menu item. Mnemonics are shortcuts for GUI elements such as text 20 | /// entries or buttons; they appear as underlined characters. See 21 | /// gtk_label_new_with_mnemonic(). Menu items can have both accelerators and 22 | /// mnemonics, of course. 23 | pub const AccelGroup = struct { 24 | ptr: *c.GtkAccelGroup, 25 | 26 | const Self = @This(); 27 | 28 | /// Creates a new GtkAccelGroup. 29 | pub fn new() Self { 30 | return Self{ .ptr = c.gtk_accel_group_new() }; 31 | } 32 | 33 | /// Installs an accelerator in this group. When accel_group is being 34 | /// activated in response to a call to gtk_accel_groups_activate(), closure 35 | /// will be invoked if the accel_key and accel_mods from 36 | /// gtk_accel_groups_activate() match those of this connection. 37 | /// 38 | /// The signature used for the closure is that of GtkAccelGroupActivate. 39 | /// 40 | /// Note that, due to implementation details, a single closure can only be 41 | /// connected to one accelerator group. 42 | pub fn connect( 43 | self: Self, 44 | /// key value of the accelerator 45 | accel_key: c_uint, 46 | /// modifier combination of the accelerator 47 | accel_mods: c.GdkModifierType, 48 | /// a flag mask to configure this accelerator 49 | accel_flags: AccelFlags, 50 | /// closure to be executed upon accelerator activation 51 | closure: *c.GClosure, 52 | ) void { 53 | c.gtk_accel_group_connect(self.ptr, accel_key, accel_mods, @enumToInt(accel_flags), closure); 54 | } 55 | }; 56 | -------------------------------------------------------------------------------- /src/actionable.zig: -------------------------------------------------------------------------------- 1 | const c = @import("cimport.zig"); 2 | const std = @import("std"); 3 | const fmt = std.fmt; 4 | const mem = std.mem; 5 | 6 | const button = @import("button.zig"); 7 | const Button = button.Button; 8 | const CheckButton = button.CheckButton; 9 | const Widget = @import("widget.zig").Widget; 10 | 11 | /// This interface provides a convenient way of associating widgets with actions 12 | /// on an ApplicationWindow or Application. 13 | /// 14 | /// It primarily consists of two properties: “action-name” and “action-target”. 15 | /// There are also some convenience APIs for setting these properties. 16 | /// 17 | /// The action will be looked up in action groups that are found among the widgets 18 | /// ancestors. Most commonly, these will be the actions with the “win.” or “app.” 19 | /// prefix that are associated with the ApplicationWindow or Application, but other 20 | /// action groups that are added with Widget.insert_action_group() will be consulted 21 | /// as well. 22 | pub const Actionable = struct { 23 | ptr: *c.GtkActionable, 24 | 25 | const Self = @This(); 26 | 27 | /// Gets the action name for actionable . 28 | /// 29 | /// See set_action_name() for more information. 30 | pub fn get_action_name(self: Self, allocator: mem.Allocator) ?[:0]const u8 { 31 | const val = c.gtk_actionable_get_action_name(self.ptr); 32 | const len = mem.len(val); 33 | return fmt.allocPrintZ(allocator, "{s}", .{val[0..len]}) catch return null; 34 | } 35 | 36 | /// Specifies the name of the action with which this widget should be associated. 37 | /// If action_name is `null` then the widget will be unassociated from any previous 38 | /// action. 39 | /// 40 | /// Usually this function is used when the widget is located (or will be located) 41 | /// within the hierarchy of a GtkApplicationWindow. 42 | /// 43 | /// Names are of the form “win.save” or “app.quit” for actions on the containing 44 | /// ApplicationWindow or its associated Application, respectively. This is the 45 | /// same form used for actions in the GMenu associated with the window. 46 | pub fn set_action_name(self: Self, name: ?[:0]const u8) void { 47 | c.gtk_actionable_get_action_name(self.ptr, if (name) |n| n.ptr else null); 48 | } 49 | 50 | /// Gets the current target value of actionable . 51 | /// 52 | /// See set_action_target_value() for more information. 53 | pub fn get_action_target_value(self: Self) c.GVariant { 54 | return c.gtk_actionable_get_target_value(self.ptr); 55 | } 56 | 57 | /// Sets the target value of an actionable widget. 58 | /// 59 | /// If target_value is NULL then the target value is unset. 60 | /// 61 | /// The target value has two purposes. First, it is used as the parameter to 62 | /// activation of the action associated with the GtkActionable widget. Second, 63 | /// it is used to determine if the widget should be rendered as “active” — the 64 | /// widget is active if the state is equal to the given target. 65 | /// 66 | /// Consider the example of associating a set of buttons with a GAction with string 67 | /// state in a typical “radio button” situation. Each button will be associated with 68 | /// the same action, but with a different target value for that action. Clicking on 69 | /// a particular button will activate the action with the target of that button, which 70 | /// will typically cause the action’s state to change to that value. Since the action’s 71 | /// state is now equal to the target value of the button, the button will now be 72 | /// rendered as active (and the other buttons, with different targets, rendered 73 | /// inactive). 74 | pub fn set_action_target_value(self: Self, target: ?*c.GVariant) void { 75 | c.gtk_actionable_set_action_target_value(self.ptr, if (target) |t| t else null); 76 | } 77 | 78 | /// Sets the target of an actionable widget. 79 | /// 80 | /// This is a convenience function that calls g_variant_new() for format_string and 81 | /// uses the result to call set_action_target_value(). 82 | /// 83 | /// If you are setting a string-valued target and want to set the action name at the 84 | /// same time, you can use set_detailed_action_name(). 85 | pub fn set_action_target(self: Self, format: [:0]const u8, args: anytype) void { 86 | c.gtk_actionable_set_action_target(self.ptr, format.ptr, args); 87 | } 88 | 89 | /// Sets the action-name and associated string target value of an actionable widget. 90 | /// 91 | /// name is a string in the format accepted by g_action_parse_detailed_name(). 92 | /// 93 | /// > (Note that prior to version 3.22.25, this function is only usable for actions 94 | /// > with a simple "s" target, and detailed_action_name must be of the form 95 | /// > "action::target" where action is the action name and target is the string to 96 | /// use as the target.) 97 | pub fn set_detailed_action_name(self: Self, name: [:0]const u8) void { 98 | c.gtk_actionable_set_detailed_action_name(self.ptr, name.ptr); 99 | } 100 | 101 | pub fn is_instance(gtype: u64) bool { 102 | return (gtype == c.gtk_actionable_get_type()); 103 | } 104 | 105 | fn get_g_type(self: Self) u64 { 106 | return self.ptr.*.parent_instance.g_type_instance.g_class.*.g_type; 107 | } 108 | 109 | pub fn isa(self: Self, comptime T: type) bool { 110 | return T.is_instance(self.get_g_type()); 111 | } 112 | 113 | pub fn to_button(self: Self) ?Button { 114 | return if (self.isa(Button)) Button{ 115 | .ptr = @ptrCast(*c.GtkButton, self.ptr), 116 | } else null; 117 | } 118 | 119 | pub fn to_check_button(self: Self) ?CheckButton { 120 | return if (self.isa(CheckButton)) CheckButton{ 121 | .ptr = @ptrCast(*c.GtkCheckButton, self.ptr), 122 | } else null; 123 | } 124 | }; 125 | -------------------------------------------------------------------------------- /src/actionbar.zig: -------------------------------------------------------------------------------- 1 | const c = @import("cimport.zig"); 2 | const Bin = @import("bin.zig").Bin; 3 | const Buildable = @import("buildable.zig").Buildable; 4 | const Container = @import("container.zig").Container; 5 | const Widget = @import("widget.zig").Widget; 6 | 7 | /// GtkActionBar is designed to present contextual actions. It is expected to be 8 | /// displayed below the content and expand horizontally to fill the area. 9 | /// 10 | /// It allows placing children at the start or the end. In addition, it contains 11 | /// an internal centered box which is centered with respect to the full width of 12 | /// the box, even if the children at either side take up different amounts of space. 13 | /// # CSS 14 | /// GtkActionBar has a single CSS node with name actionbar. 15 | pub const ActionBar = struct { 16 | ptr: *c.GtkActionBar, 17 | 18 | const Self = @This(); 19 | 20 | /// Creates a new ActionBar widget. 21 | pub fn new() Self { 22 | return Self{ 23 | .ptr = @ptrCast(*c.GtkActionBar, c.gtk_action_bar_new()), 24 | }; 25 | } 26 | 27 | /// Adds child to action_bar, packed with reference to the start of the 28 | /// action_bar. 29 | pub fn pack_start(self: Self, child: Widget) void { 30 | c.gtk_action_bar_pack_start(self.ptr, child.ptr); 31 | } 32 | 33 | /// Adds child to action_bar, packed with reference to the end of the action_bar. 34 | pub fn pack_end(self: Self, child: Widget) void { 35 | c.gtk_action_bar_pack_end(self.ptr, child.ptr); 36 | } 37 | 38 | /// Retrieves the center bar widget of the bar. 39 | pub fn get_center_widget(self: Self) ?Widget { 40 | return if (c.gtk_action_bar_get_center_widget(self.ptr)) |w| Widget{ 41 | .ptr = w, 42 | } else null; 43 | } 44 | 45 | /// Sets the center widget for the GtkActionBar. 46 | pub fn set_center_widget(self: Self, child: Widget) void { 47 | c.gtk_action_bar_set_center_widget(self.ptr, child.ptr); 48 | } 49 | 50 | pub fn as_buildable(self: Self) Buildable { 51 | return Buildable{ 52 | .ptr = @ptrCast(*c.GtkBuildable, self.ptr), 53 | }; 54 | } 55 | 56 | pub fn as_container(self: Self) Container { 57 | return Container{ 58 | .ptr = @ptrCast(*c.GtkContainer, self.ptr), 59 | }; 60 | } 61 | 62 | pub fn as_widget(self: Self) Widget { 63 | return Widget{ 64 | .ptr = @ptrCast(*c.GtkWidget, self.ptr), 65 | }; 66 | } 67 | 68 | pub fn is_instance(gtype: u64) bool { 69 | return (gtype == c.gtk_action_bar_get_type()); 70 | } 71 | }; 72 | -------------------------------------------------------------------------------- /src/adjustment.zig: -------------------------------------------------------------------------------- 1 | const c = @import("cimport.zig"); 2 | const signal_connect = @import("common.zig").signal_connect; 3 | 4 | /// The GtkAdjustment object represents a value which has an associated lower 5 | /// and upper bound, together with step and page increments, and a page size. 6 | /// It is used within several GTK+ widgets, including GtkSpinButton, 7 | /// GtkViewport, and GtkRange (which is a base class for GtkScrollbar and 8 | /// GtkScale). 9 | /// 10 | /// The GtkAdjustment object does not update the value itself. Instead it is 11 | /// left up to the owner of the GtkAdjustment to control the value. 12 | pub const Adjustment = struct { 13 | ptr: *c.GtkAdjustment, 14 | 15 | const Self = @This(); 16 | 17 | /// Create a new Adjustment 18 | pub fn new(val: f64, lower: f64, upper: f64, step: f64, page: f64, page_size: f64) Self { 19 | return Self{ 20 | .ptr = c.gtk_adjustment_new(val, lower, upper, step, page, page_size), 21 | }; 22 | } 23 | 24 | /// Gets the current value of the adjustment. See set_value(). 25 | pub fn get_value(self: Adjustment) f64 { 26 | return c.gtk_adjustment_get_value(self.ptr); 27 | } 28 | 29 | /// Sets the GtkAdjustment value. The value is clamped to lie between 30 | /// “lower” and “upper”. 31 | /// 32 | /// Note that for adjustments which are used in a GtkScrollbar, the 33 | /// effective range of allowed values goes from “lower” to “upper” - 34 | /// “page-size”. 35 | pub fn set_value(self: Adjustment, value: f64) void { 36 | c.gtk_adjustment_set_value(self.ptr, value); 37 | } 38 | 39 | /// Updates the “value” property to ensure that the range between lower and 40 | /// upper is in the current page (i.e. between “value” and “value” + 41 | /// “page-size”). If the range is larger than the page size, then only the 42 | /// start of it will be in the current page. 43 | pub fn clamp_page(self: Adjustment, lower: f64, upper: f64) void { 44 | c.gtk_adjustment_clamp_page(self.ptr, lower, upper); 45 | } 46 | 47 | /// Sets all properties of the adjustment at once. 48 | /// 49 | /// Use this function to avoid multiple emissions of the “changed” signal. 50 | /// See gtk_adjustment_set_lower() for an alternative way of compressing 51 | /// multiple emissions of “changed” into one. 52 | pub fn configure( 53 | self: Self, 54 | value: f64, 55 | lower: f64, 56 | upper: f64, 57 | step_inc: f64, 58 | page_inc: f64, 59 | page_size: f64, 60 | ) void { 61 | c.gtk_adjustment_configure(self.ptr, value, lower, upper, step_inc, page_inc, page_size); 62 | } 63 | 64 | /// Retrieves the minimum value of the adjustment. 65 | pub fn get_lower(self: Self) f64 { 66 | return c.gtk_adjustment_get_lower(self.ptr); 67 | } 68 | 69 | /// Retrieves the page increment of the adjustment. 70 | pub fn get_page_increment(self: Self) f64 { 71 | return c.gtk_adjustment_get_page_increment(self.ptr); 72 | } 73 | 74 | /// Retrieves the page size of the adjustment. 75 | pub fn get_page_size(self: Self) f64 { 76 | return c.gtk_adjustment_get_page_size(self.ptr); 77 | } 78 | 79 | /// Retrieves the step increment of the adjustment. 80 | pub fn get_step_increment(self: Self) f64 { 81 | return c.gtk_adjustment_get_step_increment(self.ptr); 82 | } 83 | 84 | /// Gets the smaller of step increment and page increment. 85 | pub fn get_minimum_increment(self: Self) f64 { 86 | return c.gtk_adjustment_get_minimum_increment(self.ptr); 87 | } 88 | 89 | /// Retrieves the maximum value of the adjustment. 90 | pub fn get_upper(self: Self) f64 { 91 | return c.gtk_adjustment_get_upper(self.ptr); 92 | } 93 | 94 | /// Sets the minimum value of the adjustment. 95 | /// 96 | /// When setting multiple adjustment properties via their individual 97 | /// setters, multiple “changed” signals will be emitted. However, since the 98 | /// emission of the “changed” signal is tied to the emission of the “notify” 99 | /// signals of the changed properties, it’s possible to compress the 100 | /// “changed” signals into one by calling g_object_freeze_notify() and 101 | /// g_object_thaw_notify() around the calls to the individual setters. 102 | /// 103 | /// Alternatively, using a single g_object_set() for all the properties to 104 | /// change, or using gtk_adjustment_configure() has the same effect of 105 | /// compressing “changed” emissions. 106 | pub fn set_lower(self: Self, lower: f64) void { 107 | c.gtk_adjustment_set_lower(self.ptr, lower); 108 | } 109 | 110 | /// Sets the page increment of the adjustment. 111 | /// 112 | /// See gtk_adjustment_set_lower() about how to compress multiple emissions 113 | /// of the “changed” signal when setting multiple adjustment properties. 114 | pub fn set_page_increment(self: Self, inc: f64) void { 115 | c.gtk_adjustment_set_page_increment(self.ptr, inc); 116 | } 117 | 118 | /// Sets the page size of the adjustment. 119 | /// 120 | /// See gtk_adjustment_set_lower() about how to compress multiple emissions 121 | /// of the GtkAdjustment::changed signal when setting multiple adjustment 122 | /// properties. 123 | pub fn set_page_size(self: Self, size: f64) void { 124 | c.gtk_adjustment_set_page_size(self.ptr, size); 125 | } 126 | 127 | /// Sets the step increment of the adjustment. 128 | /// 129 | /// See gtk_adjustment_set_lower() about how to compress multiple emissions 130 | /// of the “changed” signal when setting multiple adjustment properties. 131 | pub fn set_step_increment(self: Self, inc: f64) void { 132 | c.gtk_adjustment_set_step_increment(self.ptr, inc); 133 | } 134 | 135 | /// Sets the maximum value of the adjustment. 136 | /// 137 | /// See gtk_adjustment_set_lower() about how to compress multiple emissions 138 | /// of the “changed” signal when setting multiple adjustment properties. 139 | pub fn set_upper(self: Self, upper: f64) void { 140 | c.gtk_adjustment_set_upper(self.ptr, upper); 141 | } 142 | 143 | /// Emitted when one or more of the Adjustment properties have been changed, 144 | /// other than the “value” property. 145 | pub fn connect_changed(self: Self, callback: c.GCallback, data: ?c.gpointer) void { 146 | _ = signal_connect(self.ptr, "changed", callback, if (data) |d| d else null); 147 | } 148 | 149 | /// Emitted when the “value” property has been changed. 150 | pub fn connect_value_changed(self: Self, callback: c.GCallback, data: ?c.gpointer) void { 151 | _ = signal_connect(self.ptr, "value-changed", callback, if (data) |d| d else null); 152 | } 153 | }; 154 | -------------------------------------------------------------------------------- /src/bin.zig: -------------------------------------------------------------------------------- 1 | const c = @import("cimport.zig"); 2 | const Button = @import("button.zig").Button; 3 | const Expander = @import("expander.zig").Expander; 4 | const Frame = @import("frame.zig").Frame; 5 | const Widget = @import("widget.zig").Widget; 6 | 7 | const std = @import("std"); 8 | 9 | /// The GtkBin widget is a container with just one child. It is not very useful 10 | /// itself, but it is useful for deriving subclasses, since it provides common 11 | /// code needed for handling a single child widget. 12 | pub const Bin = struct { 13 | ptr: *c.GtkBin, 14 | 15 | const Self = @This(); 16 | 17 | /// Gets the child of the GtkBin, or `null` if the bin contains no child 18 | /// widget. The returned widget does not have a reference added, so you do 19 | /// not need to unref it. 20 | pub fn get_child(self: Self) ?Widget { 21 | return if (c.gtk_bin_get_child(self.ptr)) |ch| Widget{ 22 | .ptr = ch, 23 | } else null; 24 | } 25 | 26 | pub fn as_widget(self: Self) Widget { 27 | return Widget{ 28 | .ptr = @ptrCast(*c.GtkWidget, self.ptr), 29 | }; 30 | } 31 | 32 | pub fn is_instance(gtype: u64) bool { 33 | return (gtype == c.gtk_bin_get_type()); 34 | } 35 | 36 | fn get_g_type(self: Self) u64 { 37 | return self.ptr.*.parent_instance.g_type_instance.g_class.*.g_type; 38 | } 39 | 40 | pub fn isa(self: Self, comptime T: type) bool { 41 | return T.is_instance(self.get_g_type()); 42 | } 43 | 44 | pub fn to_button(self: Self) ?Button { 45 | return if (self.isa(Button)) Button{ 46 | .ptr = @ptrCast(*c.GtkButton, self.ptr), 47 | } else null; 48 | } 49 | 50 | pub fn to_expander(self: Self) ?Expander { 51 | return if (self.isa(Expander)) Expander{ 52 | .ptr = @ptrCast(*c.GtkExpander, self.ptr), 53 | } else null; 54 | } 55 | 56 | pub fn to_frame(self: Self) ?Frame { 57 | return if (self.isa(Frame)) Frame{ 58 | .ptr = @ptrCast(*c.GtkFrame, self.ptr), 59 | } else null; 60 | } 61 | }; 62 | -------------------------------------------------------------------------------- /src/box.zig: -------------------------------------------------------------------------------- 1 | const c = @import("cimport.zig"); 2 | 3 | const Buildable = @import("buildable.zig").Buildable; 4 | const Container = @import("container.zig").Container; 5 | const BaselinePosition = enums.BaselinePosition; 6 | const Orientable = @import("orientable.zig").Orientable; 7 | const StackSwitcher = @import("stack.zig").StackSwitcher; 8 | const Widget = @import("widget.zig").Widget; 9 | 10 | const enums = @import("enums.zig"); 11 | const Orientation = enums.Orientation; 12 | const PackType = enums.PackType; 13 | 14 | /// The GtkBox widget arranges child widgets into a single row or column, 15 | /// depending upon the value of its “orientation” property. Within the other 16 | /// dimension, all children are allocated the same size. Of course, the “halign” 17 | /// and “valign” properties can be used on the children to influence their 18 | /// allocation. 19 | /// 20 | /// GtkBox uses a notion of packing. Packing refers to adding widgets with 21 | /// reference to a particular position in a GtkContainer. For a GtkBox, there 22 | /// are two reference positions: the start and the end of the box. For a 23 | /// vertical GtkBox, the start is defined as the top of the box and the end is 24 | /// defined as the bottom. For a horizontal GtkBox the start is defined as the 25 | /// left side and the end is defined as the right side. 26 | /// 27 | /// Use repeated calls to gtk_box_pack_start() to pack widgets into a GtkBox 28 | /// from start to end. Use gtk_box_pack_end() to add widgets from end to start. 29 | /// You may intersperse these calls and add widgets from both ends of the same 30 | /// GtkBox. 31 | /// 32 | /// Because GtkBox is a GtkContainer, you may also use gtk_container_add() to 33 | /// insert widgets into the box, and they will be packed with the default values 34 | /// for expand and fill child properties. Use gtk_container_remove() to remove 35 | /// widgets from the GtkBox. 36 | /// 37 | /// Use gtk_box_set_homogeneous() to specify whether or not all children of the 38 | /// GtkBox are forced to get the same amount of space. 39 | /// 40 | /// Use gtk_box_set_spacing() to determine how much space will be minimally 41 | /// placed between all children in the GtkBox. Note that spacing is added 42 | /// between the children, while padding added by gtk_box_pack_start() or 43 | /// gtk_box_pack_end() is added on either side of the widget it belongs to. 44 | /// 45 | /// Use gtk_box_reorder_child() to move a GtkBox child to a different place in 46 | /// the box. 47 | /// 48 | /// Use gtk_box_set_child_packing() to reset the expand, fill and padding child 49 | /// properties. Use gtk_box_query_child_packing() to query these fields. 50 | /// ### CSS 51 | /// GtkBox uses a single CSS node with name box. 52 | /// 53 | /// In horizontal orientation, the nodes of the children are always arranged 54 | /// from left to right. So :first-child will always select the leftmost child, 55 | /// regardless of text direction. 56 | pub const Box = struct { 57 | ptr: *c.GtkBox, 58 | 59 | const Self = @This(); 60 | 61 | pub const Packing = struct { 62 | expand: bool, 63 | fill: bool, 64 | padding: c_uint, 65 | pack_type: PackType, 66 | }; 67 | 68 | /// Creates a new GtkBox. 69 | pub fn new(orientation: Orientation, spacing: c_int) Self { 70 | return Self{ 71 | .ptr = @ptrCast(*c.GtkBox, c.gtk_box_new(@enumToInt(orientation), spacing)), 72 | }; 73 | } 74 | 75 | /// Adds child to box , packed with reference to the start of box . The 76 | /// child is packed after any other child packed with reference to the start 77 | /// of box. 78 | pub fn pack_start(self: Self, widget: Widget, expand: bool, fill: bool, padding: c_uint) void { 79 | c.gtk_box_pack_start(self.ptr, widget.ptr, if (expand) 1 else 0, if (fill) 1 else 0, padding); 80 | } 81 | 82 | /// Adds child to box , packed with reference to the end of box. The child 83 | /// is packed after (away from end of) any other child packed with reference 84 | /// to the end of box. 85 | pub fn pack_end(self: Self, widget: Widget, expand: bool, fill: bool, padding: c_uint) void { 86 | c.gtk_box_pack_end(self.ptr, widget.ptr, if (expand) 1 else 0, if (fill) 1 else 0, padding); 87 | } 88 | 89 | /// Returns whether the box is homogeneous (all children are the same size). 90 | /// See gtk_box_set_homogeneous(). 91 | pub fn get_homogeneous(self: Self) bool { 92 | return (c.gtk_box_get_homogeneous(self.ptr) == 1); 93 | } 94 | 95 | /// Sets the “homogeneous” property of box , controlling whether or not all 96 | /// children of box are given equal space in the box. 97 | pub fn set_homogeneous(self: Self, hom: bool) void { 98 | c.gtk_box_set_homogeneous(self.ptr, if (hom) 1 else 0); 99 | } 100 | 101 | /// Gets the value set by gtk_box_set_spacing(). 102 | pub fn get_spacing(self: Self) c_int { 103 | return c.gtk_box_get_spacing(self.ptr); 104 | } 105 | 106 | /// Sets the “spacing” property of box , which is the number of pixels to 107 | /// place between children of box. 108 | pub fn set_spacing(self: Self, spacing: c_int) void { 109 | c.gtk_box_set_spacing(self.ptr, spacing); 110 | } 111 | 112 | /// Moves child to a new position in the list of box children. The list 113 | /// contains widgets packed GTK_PACK_START as well as widgets packed 114 | /// GTK_PACK_END, in the order that these widgets were added to box. 115 | /// 116 | /// A widget’s position in the box children list determines where the widget 117 | /// is packed into box . A child widget at some position in the list will be 118 | /// packed just after all other widgets of the same packing type that appear 119 | /// earlier in the list. 120 | pub fn reorder_child(self: Self, child: Widget, position: c_int) void { 121 | c.gtk_box_reorder_child(self.ptr, child.ptr, position); 122 | } 123 | 124 | /// Obtains information about how child is packed into box. 125 | pub fn query_child_packing(self: Self, child: Widget) Packing { 126 | var expand: c_int = undefined; 127 | var fill: c_int = undefined; 128 | var padding: c_uint = undefined; 129 | var pack_type: c.GtkPackType = undefined; 130 | c.gtk_box_query_packing(self.ptr, child.ptr, expand, fill, padding, pack_type); 131 | return Packing{ 132 | .expand = (expand == 1), 133 | .fill = (fill == 1), 134 | .padding = padding, 135 | .pack_type = pack_type, 136 | }; 137 | } 138 | 139 | /// Sets the way child is packed into box. 140 | pub fn set_child_packing( 141 | self: Self, 142 | child: Widget, 143 | expand: bool, 144 | fill: bool, 145 | padding: c_uint, 146 | pack_type: PackType, 147 | ) void { 148 | c.gtk_box_set_child_packing( 149 | self.ptr, 150 | child.ptr, 151 | if (expand) 1 else 0, 152 | if (fill) 1 else 0, 153 | padding, 154 | @enumToInt(pack_type), 155 | ); 156 | } 157 | 158 | /// Gets the value set by gtk_box_set_baseline_position(). 159 | pub fn get_baseline_position(self: Self) BaselinePosition { 160 | return @intToEnum(BaselinePosition, c.gtk_box_get_baseline_position(self.ptr)); 161 | } 162 | 163 | /// Sets the baseline position of a box. This affects only horizontal boxes 164 | /// with at least one baseline aligned child. If there is more vertical 165 | /// space available than requested, and the baseline is not allocated by the 166 | /// parent then position is used to allocate the baseline wrt the extra 167 | /// space available. 168 | pub fn set_baseline_position(self: Self, pos: BaselinePosition) void { 169 | c.gtk_box_set_baseline_position(self.ptr, @enumToInt(pos)); 170 | } 171 | 172 | pub fn get_center_widget(self: Self) Widget { 173 | return Widget{ 174 | .ptr = c.gtk_box_get_center_widget(self.ptr), 175 | }; 176 | } 177 | 178 | pub fn set_center_widget(self: Self, child: Widget) void { 179 | c.gtk_box_set_center_widget(self.ptr, child.ptr); 180 | } 181 | 182 | pub fn as_buildable(self: Self) Buildable { 183 | return Buildable{ 184 | .ptr = @ptrCast(*c.GtkBuildable, self.ptr), 185 | }; 186 | } 187 | 188 | pub fn as_container(self: Self) Container { 189 | return Container{ 190 | .ptr = @ptrCast(*c.GtkContainer, self.ptr), 191 | }; 192 | } 193 | 194 | pub fn as_orientable(self: Self) Orientable { 195 | return Orientable{ 196 | .ptr = @ptrCast(*c.GtkOrientable, self.ptr), 197 | }; 198 | } 199 | 200 | pub fn as_widget(self: Self) Widget { 201 | return Widget{ 202 | .ptr = @ptrCast(*c.GtkWidget, self.ptr), 203 | }; 204 | } 205 | 206 | pub fn is_instance(gtype: u64) bool { 207 | return (gtype == c.gtk_box_get_type()); 208 | } 209 | 210 | fn get_g_type(self: Self) u64 { 211 | return self.ptr.*.parent_instance.g_type_instance.g_class.*.g_type; 212 | } 213 | 214 | pub fn isa(self: Self, comptime T: type) bool { 215 | return T.is_instance(self.get_g_type()); 216 | } 217 | 218 | pub fn to_stack_switcher(self: Self) ?StackSwitcher { 219 | return if (self.isa(StackSwitcher)) StackSwitcher{ .ptr = @ptrCast(*c.GtkStackSwitcher, self.ptr) } else null; 220 | } 221 | }; 222 | -------------------------------------------------------------------------------- /src/buildable.zig: -------------------------------------------------------------------------------- 1 | const c = @import("cimport.zig"); 2 | const Builder = @import("builder.zig").Builder; 3 | const Widget = @import("widget.zig").Widget; 4 | const std = @import("std"); 5 | const fmt = std.fmt; 6 | const mem = std.mem; 7 | 8 | pub const Buildable = struct { 9 | ptr: *c.GtkBuildable, 10 | 11 | const Self = @This(); 12 | 13 | pub fn set_name(self: Self, name: [:0]const u8) void { 14 | c.gtk_buildable_set_name(self.ptr, name.ptr); 15 | } 16 | 17 | pub fn get_name(self: Self, allocator: mem.Allocator) ?[:0]const u8 { 18 | const val = c.gtk_buildable_get_name(self.ptr); 19 | const len = mem.len(val); 20 | return fmt.allocPrintZ(allocator, "{s}", .{val[0..len]}) catch return null; 21 | } 22 | 23 | pub fn add_child(self: Self, builder: Builder, child: *c.GObject, kind: ?[:0]const u8) void { 24 | c.gtk_buildable_add_child( 25 | self.ptr, 26 | builder.ptr, 27 | child, 28 | if (kind) |k| k.ptr else null, 29 | ); 30 | } 31 | 32 | pub fn set_buildable_property(self: Self, builder: Builder, name: [:0]const u8, value: c.GValue) void { 33 | c.gtk_buildable_set_buildable_property( 34 | self.ptr, 35 | builder.ptr, 36 | name.ptr, 37 | value, 38 | ); 39 | } 40 | 41 | pub fn construct_child(self: Self, builder: Builder, name: [:0]const u8) *c.GObject { 42 | return c.gtk_buildable_construct_child(self.ptr, builder.ptr, name.ptr); 43 | } 44 | 45 | pub fn get_internal_child(self: Self, builder: Builder, name: [:0]const u8) *c.GObject { 46 | return c.gtk_buildable_get_internal_child(self.ptr, builder.ptr, name.ptr); 47 | } 48 | 49 | pub fn as_widget(self: Self) Widget { 50 | return Widget{ .ptr = @ptrCast(*c.GtkWidget, self.ptr) }; 51 | } 52 | 53 | pub fn is_instance(gtype: u64) bool { 54 | return (gtype == c.gtk_message_dialog_get_type()); 55 | } 56 | }; 57 | -------------------------------------------------------------------------------- /src/builder.zig: -------------------------------------------------------------------------------- 1 | const c = @import("cimport.zig"); 2 | const Adjustment = @import("adjustment.zig").Adjustment; 3 | const common = @import("common.zig"); 4 | const Widget = @import("widget.zig").Widget; 5 | 6 | const std = @import("std"); 7 | const mem = std.mem; 8 | 9 | const BuilderError = error{ 10 | ParseStringError, 11 | ParseFileError, 12 | }; 13 | 14 | pub const Builder = struct { 15 | ptr: *c.GtkBuilder, 16 | 17 | pub fn new() Builder { 18 | return Builder{ 19 | .ptr = c.gtk_builder_new(), 20 | }; 21 | } 22 | 23 | pub fn add_from_string(self: Builder, string: []const u8) BuilderError!void { 24 | const len = mem.len(string); 25 | var ret = c.gtk_builder_add_from_string(self.ptr, string.ptr, len, @intToPtr([*c][*c]c._GError, 0)); 26 | if (ret == 0) { 27 | //return .ParseStringError; 28 | } 29 | } 30 | 31 | pub fn get_widget(self: Builder, string: [:0]const u8) ?Widget { 32 | if (common.builder_get_widget(self.ptr, string.ptr)) |w| { 33 | return Widget{ 34 | .ptr = w, 35 | }; 36 | } else return null; 37 | } 38 | 39 | pub fn get_adjustment(self: Builder, string: [:0]const u8) ?Adjustment { 40 | if (common.builder_get_adjustment(self.ptr, string.ptr)) |a| { 41 | return Adjustment{ 42 | .ptr = a, 43 | }; 44 | } else return null; 45 | } 46 | 47 | pub fn set_application(self: Builder, app: *c.GtkApplication) void { 48 | c.gtk_builder_set_application(self.ptr, app); 49 | } 50 | }; 51 | -------------------------------------------------------------------------------- /src/button.zig: -------------------------------------------------------------------------------- 1 | const c = @import("cimport.zig"); 2 | const enums = @import("enums.zig"); 3 | const Actionable = @import("actionable.zig").Actionable; 4 | const Buildable = @import("buildable.zig").Buildable; 5 | const ColorButton = @import("colorchooser.zig").ColorButton; 6 | const IconSize = enums.IconSize; 7 | const PositionType = enums.PositionType; 8 | const ReliefStyle = enums.ReliefStyle; 9 | const Widget = @import("widget.zig").Widget; 10 | 11 | const std = @cImport("std"); 12 | const fmt = std.fmt; 13 | const mem = std.mem; 14 | 15 | pub const Button = struct { 16 | ptr: *c.GtkButton, 17 | 18 | const Self = @This(); 19 | 20 | /// Creates a new Button 21 | pub fn new() Self { 22 | return Self{ 23 | .ptr = @ptrCast(*c.GtkButton, c.gtk_button_new()), 24 | }; 25 | } 26 | 27 | /// Creates a Button with a GtkLabel containing the given text 28 | pub fn new_with_label(text: [:0]const u8) Self { 29 | return Self{ 30 | .ptr = @ptrCast(*c.GtkButton, c.gtk_button_new_with_label(text.ptr)), 31 | }; 32 | } 33 | 34 | /// Creates a new Button containing a label. Underscores in label indicate the 35 | /// mnemonic for the button. 36 | pub fn new_with_mnemonic(text: [:0]const u8) Self { 37 | return Self{ 38 | .ptr = @ptrCast(*c.GtkButton, c.gtk_button_new_with_mnemonic(text.ptr)), 39 | }; 40 | } 41 | 42 | /// Creates a new Button containing an icon from the current icon theme. 43 | pub fn new_from_icon_name(icon_name: [:0]const u8, size: IconSize) Self { 44 | return Self{ 45 | .ptr = @ptrCast(*c.GtkButton, c.gtk_button_new_from_icon_name(icon_name.ptr, @enumToInt(size))), 46 | }; 47 | } 48 | 49 | /// Get the ReliefStyle of the Button 50 | pub fn get_relief(self: Self) ReliefStyle { 51 | return c.gtk_button_get_relief(self.ptr); 52 | } 53 | 54 | /// Set the ReliefStyle of the Button 55 | pub fn set_relief(self: Self, style: ReliefStyle) void { 56 | c.gtk_button_set_relief(self.ptr, @enumToInt(style)); 57 | } 58 | 59 | /// Get the text from the label of the Button, or null if unset 60 | pub fn get_label(self: Self, allocator: mem.Allocator) ?[:0]const u8 { 61 | if (c.gtk_button_get_label(self.ptr)) |l| { 62 | const len = mem.len(l); 63 | const text = fmt.allocPrintZ(allocator, "{s}", .{l[0..len]}) catch { 64 | return null; 65 | }; 66 | return text; 67 | } else return null; 68 | } 69 | 70 | /// Set the text for the Button label 71 | pub fn set_label(self: Self, text: [:0]const u8) void { 72 | c.gtk_button_set_label(self.ptr, text.ptr); 73 | } 74 | 75 | /// Returns whether an embedded underline in the button label indicates a mnemonic. 76 | pub fn get_use_underline(self: Self) bool { 77 | return (c.gtk_button_get_use_underline(self.ptr) == 1); 78 | } 79 | 80 | /// If true, an underline in the text of the button label indicates the next 81 | /// character should be used for the mnemonic accelerator key. 82 | pub fn set_use_underline(self: Self, use: bool) void { 83 | c.gtk_button_set_use_underline(self.ptr, if (use) 1 else 0); 84 | } 85 | 86 | /// Returns true if clicking the Button causes it to receive focus 87 | pub fn get_focus_on_click(self: Self) bool { 88 | return (c.gtk_button_get_focus_on_click(self.ptr) == 1); 89 | } 90 | 91 | /// Set whether clicking a button causes it to receive focus 92 | pub fn set_focus_on_click(self: Self, foc: bool) void { 93 | c.gtk_button_set_focus_on_click(self.ptr, if (foc) 1 else 0); 94 | } 95 | 96 | /// Returns an Widget struct representing the image which is currently set, or null 97 | pub fn get_image(self: Self) ?Widget { 98 | if (c.gtk_button_get_image(self.ptr)) |w| { 99 | return Widget{ 100 | .ptr = w, 101 | }; 102 | } else return null; 103 | } 104 | 105 | /// Set the image of the button to the given widget. If image is null, unset the image. 106 | pub fn set_image(self: Self, image: ?Widget) void { 107 | c.gtk_button_set_image(self.ptr, if (image) |i| i.ptr else null); 108 | } 109 | 110 | /// Gets the position of the image relative to the text inside the button. 111 | pub fn get_image_position(self: Self) PositionType { 112 | return c.gtk_button_get_image_position(self.ptr); 113 | } 114 | 115 | /// Sets the position of the image relative to the text inside the button. 116 | pub fn set_image_position(self: Self, pos: PositionType) void { 117 | c.gtk_button_set_image_position(self.ptr, @enumToInt(pos)); 118 | } 119 | 120 | /// Returns whether the button will always show the image, if available. 121 | pub fn get_always_show_image(self: Self) bool { 122 | return (c.gtk_button_get_always_show_image(self.ptr) == 1); 123 | } 124 | 125 | /// Set whether the button will always show the image, if available. 126 | pub fn set_always_show_image(self: Self, show: bool) void { 127 | c.gtk_button_set_always_show_image(self.ptr, if (show) 1 else 0); 128 | } 129 | 130 | pub fn as_actionable(self: Self) Actionable { 131 | return Actionable{ 132 | .ptr = @ptrCast(*c.GtkActionable, self.ptr), 133 | }; 134 | } 135 | 136 | pub fn as_buildable(self: Self) Buildable { 137 | return Buildable{ 138 | .ptr = @ptrCast(*c.GtkBuildable, self.ptr), 139 | }; 140 | } 141 | 142 | /// Casts the internal pointer to a GtkWidget and returns a Widget struct 143 | pub fn as_widget(self: Self) Widget { 144 | return Widget{ 145 | .ptr = @ptrCast(*c.GtkWidget, self.ptr), 146 | }; 147 | } 148 | 149 | pub fn isa(self: Self, comptime T: type) bool { 150 | return T.is_instance(self.get_g_type()); 151 | } 152 | 153 | pub fn to_color_button(self: Self) ?ColorButton { 154 | if (self.isa(ColorButton)) { 155 | return ColorButton{ 156 | .ptr = @ptrCast(*c.GtkColorButton, self.ptr), 157 | }; 158 | } else return null; 159 | } 160 | 161 | /// Connects a callback function to the "clicked" signal 162 | pub fn connect_clicked(self: Button, callback: c.GCallback, data: ?c.gpointer) void { 163 | self.as_widget().connect("clicked", callback, if (data) |d| d else null); 164 | } 165 | 166 | pub fn is_instance(gtype: u64) bool { 167 | return (gtype == c.gtk_button_get_type() or ToggleButton.is_instance(gtype) or CheckButton.is_instance(gtype)); 168 | } 169 | }; 170 | 171 | pub const ToggleButton = struct { 172 | ptr: *c.GtkToggleButton, 173 | 174 | const Self = @This(); 175 | 176 | /// Creates a new ToggleButton. A widget should be packed into the button, as in button_new(). 177 | pub fn new() Self { 178 | return Self{ 179 | .ptr = @ptrCast(*c.GtkToggleButton, c.gtk_check_button_new()), 180 | }; 181 | } 182 | 183 | /// Creates a new ToggleButton with a text label. 184 | pub fn new_with_label(text: [:0]const u8) Self { 185 | return Self{ 186 | .ptr = @ptrCast(*c.GtkToggleButton, c.gtk_toggle_button_new_with_label(text.ptr)), 187 | }; 188 | } 189 | 190 | /// Creates a new ToggleButton containing a label. Underscores in label indicate the 191 | /// mnemonic for the button. 192 | pub fn new_with_mnemonic(text: [:0]const u8) Self { 193 | return Self{ 194 | .ptr = @ptrCast(*c.GtkToggleButton, c.gtk_toggle_button_new_with_mnemonic(text.ptr)), 195 | }; 196 | } 197 | 198 | /// Retrieves whether the button is displayed as a separate indicator and label. 199 | pub fn get_mode(self: Self) bool { 200 | return (c.gtk_toggle_button_get_mode(self.ptr) == 1); 201 | } 202 | 203 | /// Sets whether the button is displayed as a separate indicator and label. 204 | pub fn set_mode(self: Self, mode: bool) void { 205 | c.gtk_toggle_button_set_mode(self.ptr, if (mode) 1 else 0); 206 | } 207 | 208 | /// Queries a GtkToggleButton and returns its current state. 209 | /// Returns true if the toggle button is pressed in and false if it is raised. 210 | pub fn get_active(self: Self) bool { 211 | return (c.gtk_toggle_button_get_active(self.ptr) == 1); 212 | } 213 | 214 | /// Sets the status of the toggle button. 215 | /// This action causes the “toggled” signal and the “clicked” signal to be emitted. 216 | pub fn set_active(self: Self, state: bool) void { 217 | c.gtk_toggle_button_set_active(self.ptr, if (state) 1 else 0); 218 | } 219 | 220 | pub fn as_actionable(self: Self) Actionable { 221 | return Actionable{ 222 | .ptr = @ptrCast(*c.GtkActionable, self.ptr), 223 | }; 224 | } 225 | 226 | pub fn as_buildable(self: Self) Buildable { 227 | return Buildable{ 228 | .ptr = @ptrCast(*c.GtkBuildable, self.ptr), 229 | }; 230 | } 231 | 232 | /// Casts the internal pointer to a GtkButton and returns a Button struct 233 | pub fn as_button(self: Self) Button { 234 | return Button{ 235 | .ptr = @ptrCast(*c.GtkButton, self.ptr), 236 | }; 237 | } 238 | 239 | /// Casts the internal pointer to a GtkWidget and returns a Widget struct 240 | pub fn as_widget(self: Self) Widget { 241 | return Widget{ 242 | .ptr = @ptrCast(*c.GtkWidget, self.ptr), 243 | }; 244 | } 245 | 246 | pub fn isa(self: Self, comptime T: type) bool { 247 | return T.is_instance(self.get_g_type()); 248 | } 249 | 250 | pub fn to_check_button(self: Self) ?CheckButton { 251 | if (self.isa(CheckButton)) { 252 | return CheckButton{ 253 | .ptr = @ptrCast(*c.GtkCheckButton, self.ptr), 254 | }; 255 | } else return null; 256 | } 257 | 258 | /// Connects a callback function when the "toggled" signal is emitted 259 | pub fn connect_toggled(self: Self, callback: c.GCallback, data: ?c.gpointer) void { 260 | self.as_widget().connect("toggled", callback, if (data) |d| d else null); 261 | } 262 | 263 | pub fn is_instance(gtype: u64) bool { 264 | return (gtype == c.gtk_toggle_button_get_type()); 265 | } 266 | }; 267 | 268 | pub const CheckButton = struct { 269 | ptr: *c.GtkCheckButton, 270 | 271 | const Self = @This(); 272 | 273 | // Creates a new CheckButton 274 | pub fn new() Self { 275 | return Self{ 276 | .ptr = c.gtk_check_button_new(), 277 | }; 278 | } 279 | 280 | // Creates a new CheckButton with a GtkLabel to the right of it. 281 | pub fn new_with_label(text: [:0]const u8) Self { 282 | return Self{ 283 | .ptr = @ptrCast(*c.GtkCheckButton, c.gtk_check_button_new_with_label(text.ptr)), 284 | }; 285 | } 286 | 287 | // Creates a new CheckButton with a GtkLabel to the right of it. 288 | // Underscores in label indicate the mnemonic for the check button. 289 | pub fn new_with_mnemonic(text: [:0]const u8) Self { 290 | return Self{ 291 | .ptr = @ptrCast(*c.GtkCheckButton, c.gtk_check_button_new_with_mnemonic(text.ptr)), 292 | }; 293 | } 294 | 295 | pub fn as_actionable(self: Self) Actionable { 296 | return Actionable{ 297 | .ptr = @ptrCast(*c.GtkActionable, self.ptr), 298 | }; 299 | } 300 | 301 | pub fn as_buildable(self: Self) Buildable { 302 | return Buildable{ 303 | .ptr = @ptrCast(*c.GtkBuildable, self.ptr), 304 | }; 305 | } 306 | 307 | pub fn as_button(self: Self) Button { 308 | return Button{ 309 | .ptr = @ptrCast(*c.GtkButton, self.ptr), 310 | }; 311 | } 312 | 313 | pub fn as_toggle_button(self: Self) ToggleButton { 314 | return ToggleButton{ 315 | .ptr = @ptrCast(*c.GtkToggleButton, self.ptr), 316 | }; 317 | } 318 | 319 | pub fn as_widget(self: Self) Widget { 320 | return Widget{ 321 | .ptr = @ptrCast(*c.GtkWidget, self.ptr), 322 | }; 323 | } 324 | 325 | pub fn is_instance(gtype: u64) bool { 326 | return (gtype == c.gtk_check_button_get_type()); 327 | } 328 | }; 329 | -------------------------------------------------------------------------------- /src/buttonbox.zig: -------------------------------------------------------------------------------- 1 | const c = @import("cimport.zig"); 2 | const Box = @import("box.zig").Box; 3 | const Buildable = @import("buildable.zig").Buildable; 4 | const Button = @import("button.zig").Button; 5 | const Container = @import("container.zig").Container; 6 | const Orientable = @import("orientable.zig").Orientable; 7 | const Orientation = @import("enums.zig").Orientation; 8 | const Widget = @import("widget.zig").Widget; 9 | 10 | const std = @cImport("std"); 11 | const fmt = std.fmt; 12 | const mem = std.mem; 13 | 14 | /// A button box should be used to provide a consistent layout of buttons 15 | /// throughout your application. The layout/spacing can be altered by the 16 | /// programmer, or if desired, by the user to alter the “feel” of a program 17 | /// to a small degree. 18 | /// 19 | /// gtk_button_box_get_layout() and gtk_button_box_set_layout() retrieve and 20 | /// alter the method used to spread the buttons in a button box across the 21 | /// container, respectively. 22 | /// 23 | /// The main purpose of GtkButtonBox is to make sure the children have all the 24 | /// same size. GtkButtonBox gives all children the same size, but it does allow 25 | /// 'outliers' to keep their own larger size. 26 | /// 27 | /// To exempt individual children from homogeneous sizing regardless of their 28 | /// 'outlier' status, you can set the non-homogeneous child property. 29 | /// ### CSS 30 | /// GtkButtonBox uses a single CSS node with name buttonbox. 31 | pub const ButtonBox = struct { 32 | ptr: *c.GtkButtonBox, 33 | 34 | const Self = @This(); 35 | 36 | pub const Style = enum(c_uint) { 37 | spread = c.GTK_BUTTONBOX_SPREAD, 38 | edge = c.GTK_BUTTONBOX_EDGE, 39 | start = c.GTK_BUTTONBOX_START, 40 | end = c.GTK_BUTTONBOX_END, 41 | center = c.GTK_BUTTONBOX_CENTER, 42 | expand = c.GTK_BUTTONBOX_EXPAND, 43 | }; 44 | 45 | /// Creates a new GtkButtonBox. 46 | pub fn new(orientation: Orientation) Self { 47 | return Self{ 48 | .ptr = @ptrCast(*c.GtkButtonBox, c.gtk_button_box_new(orientation)), 49 | }; 50 | } 51 | 52 | /// Retrieves the method being used to arrange the buttons in a button box. 53 | pub fn get_layout(self: Self) Style { 54 | return c.gtk_button_box_get_layout(self.ptr); 55 | } 56 | 57 | /// Returns whether child should appear in a secondary group of children. 58 | pub fn get_child_secondary(self: Self, child: Widget) bool { 59 | return (c.gtk_button_box_get_child_secondary(self.ptr, child.ptr) == 1); 60 | } 61 | 62 | /// Returns whether the child is exempted from homogenous sizing. 63 | pub fn get_child_non_homogeneous(self: Self, child: Widget) bool { 64 | return (c.gtk_button_box_get_child_non_homogeneous(self.ptr, child.ptr) == 1); 65 | } 66 | 67 | /// Changes the way buttons are arranged in their container. 68 | pub fn set_layout(self: Self, layout: Style) void { 69 | c.gtk_button_box_set_layout(self.ptr, layout); 70 | } 71 | 72 | /// Sets whether child should appear in a secondary group of children. A 73 | /// typical use of a secondary child is the help button in a dialog. 74 | /// 75 | /// This group appears after the other children if the style is 76 | /// GTK_BUTTONBOX_START, GTK_BUTTONBOX_SPREAD or GTK_BUTTONBOX_EDGE, and 77 | /// before the other children if the style is GTK_BUTTONBOX_END. For 78 | /// horizontal button boxes, the definition of before/after depends on 79 | /// direction of the widget (see gtk_widget_set_direction()). If the style 80 | /// is GTK_BUTTONBOX_START or GTK_BUTTONBOX_END, then the secondary children 81 | /// are aligned at the other end of the button box from the main children. 82 | /// For the other styles, they appear immediately next to the main children. 83 | pub fn set_child_secondary(self: Self, set: bool) void { 84 | c.gtk_button_box_set_child_secondary(self.ptr, if (set) 1 else 0); 85 | } 86 | 87 | /// Sets whether the child is exempted from homogeous sizing. 88 | pub fn set_child_non_homogeneous(self: Self, child: Widget, set: bool) void { 89 | c.gtk_button_box_set_child_non_homogeneous(self.ptr, child.ptr, if (set) 1 else 0); 90 | } 91 | 92 | pub fn as_box(self: Self) Box { 93 | return Box{ 94 | .ptr = @ptrCast(*c.GtkBox, self.ptr), 95 | }; 96 | } 97 | 98 | pub fn as_buildable(self: Self) Buildable { 99 | return Buildable{ 100 | .ptr = @ptrCast(*c.GtkBuildable, self.ptr), 101 | }; 102 | } 103 | 104 | pub fn as_button(self: Self) Button { 105 | return Button{ 106 | .ptr = @ptrCast(*c.GtkButton, self.ptr), 107 | }; 108 | } 109 | 110 | pub fn as_container(self: Self) Container { 111 | return Container{ 112 | .ptr = @ptrCast(*c.GtkContainer, self.ptr), 113 | }; 114 | } 115 | 116 | pub fn as_orientable(self: Self) Orientable { 117 | return Orientable{ 118 | .ptr = @ptrCast(*c.GtkOrientable, self.ptr), 119 | }; 120 | } 121 | 122 | pub fn as_widget(self: Self) Widget { 123 | return Widget{ 124 | .ptr = @ptrCast(*c.GtkWidget, self.ptr), 125 | }; 126 | } 127 | 128 | pub fn is_instance(gtype: u64) bool { 129 | return (gtype == c.gtk_check_button_box_get_type()); 130 | } 131 | }; 132 | -------------------------------------------------------------------------------- /src/cimport.zig: -------------------------------------------------------------------------------- 1 | pub usingnamespace @cImport({ 2 | @cInclude("gtk/gtk.h"); 3 | @cInclude("libintl.h"); 4 | }); 5 | -------------------------------------------------------------------------------- /src/colorchooser.zig: -------------------------------------------------------------------------------- 1 | const c = @import("cimport.zig"); 2 | 3 | const Actionable = @import("actionable.zig").Actionable; 4 | const Button = @import("button.zig").Button; 5 | const Dialog = @import("dialog.zig").Dialog; 6 | const Widget = @import("widget.zig").Widget; 7 | 8 | const std = @import("std"); 9 | const fmt = std.fmt; 10 | const mem = std.mem; 11 | 12 | pub const ColorChooser = struct { 13 | ptr: *c.GtkColorChooser, 14 | 15 | pub fn get_rgba(self: ColorChooser) c.GdkRGBA { 16 | var rgba: c.GdkRGBA = undefined; 17 | _ = c.gtk_color_chooser_get_rgba(self.ptr, &rgba); 18 | return rgba; 19 | } 20 | 21 | pub fn set_rgba(self: ColorChooser, rgba: c.GdkRGBA) void { 22 | c.gtk_color_chooser_set_rgba(self.ptr, &rgba); 23 | } 24 | 25 | pub fn get_use_alpha(self: ColorChooser) bool { 26 | return (c.gtk_color_chooser_get_use_alpha(self.ptr) == 1); 27 | } 28 | 29 | pub fn set_use_alpha(self: ColorChooser, use: bool) void { 30 | c.gtk_color_chooser_set_use_alpha(self.ptr, if (use) 1 else 0); 31 | } 32 | 33 | pub fn is_instance(gtype: u64) bool { 34 | return (gtype == c.gtk_color_chooser_get_type() or ColorButton.is_instance(gtype) or ColorChooserWidget.is_instance(gtype) or ColorChooserDialog.is_instance(gtype)); 35 | } 36 | 37 | pub fn to_color_button(self: ColorChooser) ?ColorButton { 38 | if (self.as_widget().isa(ColorButton)) { 39 | return ColorButton{ 40 | .ptr = @ptrCast(*c.GtkColorButton, self.ptr), 41 | }; 42 | } else return null; 43 | } 44 | 45 | pub fn to_color_chooser_widget(self: ColorChooser) ?ColorChooserWidget { 46 | if (self.as_widget().isa(ColorChooserWidget)) { 47 | return ColorChooserWidget{ 48 | .ptr = @ptrCast(*c.GtkColorChooserWidget, self.ptr), 49 | }; 50 | } else return null; 51 | } 52 | 53 | pub fn to_color_chooser_dialog(self: ColorChooser) ?ColorChooserDialog { 54 | if (self.as_widget().isa(ColorChooserWidget)) { 55 | return ColorChooserDialog{ 56 | .ptr = @ptrCast(*c.GtkColorChooserDialog, self.ptr), 57 | }; 58 | } else return null; 59 | } 60 | 61 | /// Emitted when a color is activated from the color chooser. This usually 62 | /// happens when the user clicks a color swatch, or a color is selected and 63 | /// the user presses one of the keys Space, Shift+Space, Return or Enter. 64 | pub fn connect_color_activated(self: Button, callback: c.GCallback, data: ?c.gpointer) void { 65 | self.as_widget().connect("color-activated", callback, if (data) |d| d else null); 66 | } 67 | }; 68 | 69 | pub const ColorButton = struct { 70 | ptr: *c.GtkColorButton, 71 | 72 | const Self = @This(); 73 | 74 | pub fn new() Self { 75 | return Self{ 76 | .ptr = @ptrCast(*c.GtkColorButton, c.gtk_color_button_new()), 77 | }; 78 | } 79 | 80 | pub fn new_sith_rgba(rgba: c.GdkRGBA) Self { 81 | return Self{ 82 | .ptr = @ptrCast(*c.GtkColorButton, c.gtk_color_button_new_with_rgba(rgba)), 83 | }; 84 | } 85 | 86 | pub fn set_title(self: Self, title: [:0]const u8) void { 87 | c.gtk_color_button_set_title(self.ptr, title.ptr); 88 | } 89 | 90 | pub fn get_title(self: Self, allocator: mem.Allocator) ?[:0]const u8 { 91 | const val = c.gtk_color_button_get_title(self.ptr); 92 | const len = mem.len(val); 93 | return fmt.allocPrintZ(allocator, "{s}", .{val[0..len]}) catch return null; 94 | } 95 | 96 | /// The ::color-set signal is emitted when the user selects a color. When 97 | /// handling this signal, use gtk_color_button_get_rgba() to find out which 98 | /// color was just selected. 99 | /// 100 | /// Note that this signal is only emitted when the user changes the color. 101 | /// If you need to react to programmatic color changes as well, use the 102 | /// notify::color signal. 103 | pub fn connect_color_set(self: Self, callback: c.GCallback, data: ?c.gpointer) void { 104 | self.as_widget().connect("color-set", callback, if (data) |d| d else null); 105 | } 106 | 107 | pub fn as_actionable(self: Self) Actionable { 108 | return Actionable{ 109 | .ptr = @ptrCast(*c.GtkActionable, self.ptr), 110 | }; 111 | } 112 | 113 | pub fn as_button(self: Self) Button { 114 | return Button{ 115 | .ptr = @ptrCast(*c.GtkButton, self.ptr), 116 | }; 117 | } 118 | 119 | pub fn as_color_chooser(self: Self) ColorChooser { 120 | return ColorChooser{ 121 | .ptr = @ptrCast(*c.GtkColorChooser, self.ptr), 122 | }; 123 | } 124 | 125 | pub fn as_widget(self: Self) Widget { 126 | return Widget{ 127 | .ptr = @ptrCast(*c.GtkWidget, self.ptr), 128 | }; 129 | } 130 | 131 | pub fn is_instance(gtype: u64) bool { 132 | return (gtype == c.gtk_color_button_get_type()); 133 | } 134 | }; 135 | 136 | pub const ColorChooserWidget = struct { 137 | ptr: *c.GtkColorChooserWidget, 138 | 139 | const Self = @This(); 140 | 141 | pub fn as_color_chooser(self: Self) ColorChooser { 142 | return ColorChooser{ 143 | .ptr = @ptrCast(*c.GtkColorChooser, self.ptr), 144 | }; 145 | } 146 | 147 | pub fn is_instance(gtype: u64) bool { 148 | return (gtype == c.gtk_color_chooser_widget_get_type()); 149 | } 150 | }; 151 | 152 | pub const ColorChooserDialog = struct { 153 | ptr: *c.GtkColorChooserDialog, 154 | 155 | const Self = @This(); 156 | 157 | pub fn as_color_chooser(self: Self) ColorChooser { 158 | return ColorChooser{ 159 | .ptr = @ptrCast(*c.GtkColorChooser, self.ptr), 160 | }; 161 | } 162 | 163 | pub fn as_dialog(self: Self) Dialog { 164 | return Dialog{ 165 | .ptr = @ptrCast(*c.GtkDialog, self.ptr), 166 | }; 167 | } 168 | 169 | pub fn is_instance(gtype: u64) bool { 170 | return (gtype == c.gtk_color_chooser_dialog_get_type()); 171 | } 172 | }; 173 | -------------------------------------------------------------------------------- /src/combobox.zig: -------------------------------------------------------------------------------- 1 | const c = @import("cimport.zig"); 2 | const common = @import("common.zig"); 3 | const Widget = @import("widget.zig").Widget; 4 | 5 | const std = @import("std"); 6 | const fmt = std.fmt; 7 | const mem = std.mem; 8 | 9 | pub const ComboBox = struct { 10 | ptr: *c.GtkComboBox, 11 | 12 | const Self = @This(); 13 | 14 | pub fn new() Self { 15 | return Self{ 16 | .ptr = @ptrCast(*c.GtkComboBox, c.gtk_combo_box_new()), 17 | }; 18 | } 19 | 20 | pub fn new_with_entry() Self { 21 | return Self{ 22 | .ptr = @ptrCast(*c.GtkComboBox, c.gtk_combo_box_new_with_entry()), 23 | }; 24 | } 25 | 26 | pub fn get_active(self: Self) ?c_int { 27 | const res = c.gtk_combo_box_get_active(self.ptr); 28 | return switch (res) { 29 | -1 => null, 30 | else => res, 31 | }; 32 | } 33 | 34 | pub fn set_active(self: Self, item: ?c_int) void { 35 | c.gtk_commbo_box_set_active(self.ptr, if (item) |i| i else -1); 36 | } 37 | 38 | pub fn get_active_id(self: Self, allocator: mem.Allocator) ?[:0]const u8 { 39 | if (c.gtk_combo_box_get_active_id(self.ptr)) |val| { 40 | const len = mem.len(val); 41 | return fmt.allocPrintZ(allocator, "{s}", .{val[0..len]}) catch return null; 42 | } else return null; 43 | } 44 | 45 | pub fn set_active_id(self: Self, id: ?[:0]const u8) void { 46 | _ = c.gtk_combo_box_set_active_id(self.ptr, if (id) |i| i.ptr else null); 47 | } 48 | 49 | pub fn connect_changed(self: Self, callback: c.GCallback, data: ?c.gpointer) void { 50 | self.as_widget().connect("changed", callback, if (data) |d| d else null); 51 | } 52 | 53 | pub fn as_widget(self: Self) Widget { 54 | return Widget{ 55 | .ptr = @ptrCast(*c.GtkWidget, self.ptr), 56 | }; 57 | } 58 | 59 | fn get_g_type(self: Self) u64 { 60 | return self.ptr.*.parent_instance.g_type_instance.g_class.*.g_type; 61 | } 62 | 63 | pub fn isa(self: Self, comptime T: type) bool { 64 | return T.is_instance(self.get_g_type()); 65 | } 66 | 67 | pub fn to_combo_box_text(self: Self) ?ComboBoxText { 68 | if (self.isa(ComboBoxText)) { 69 | return ComboBoxText{ 70 | .ptr = @ptrCast(*c.GtkComboBoxText, self.ptr), 71 | }; 72 | } else return null; 73 | } 74 | 75 | pub fn is_instance(gtype: u64) bool { 76 | return (gtype == c.gtk_combo_box_get_type() or ComboBoxText.is_instance(gtype)); 77 | } 78 | }; 79 | 80 | pub const ComboBoxText = struct { 81 | ptr: *c.GtkComboBoxText, 82 | 83 | const Self = @This(); 84 | 85 | pub fn new() Self { 86 | return Self{ 87 | .ptr = c.gtk_combo_box_text_new(), 88 | }; 89 | } 90 | 91 | pub fn new_with_entry() Self { 92 | return Self{ 93 | .ptr = c.gtk_combo_box_text_new_with_entry(), 94 | }; 95 | } 96 | 97 | pub fn append(self: Self, id: ?[:0]const u8, text: [:0]const u8) void { 98 | c.gtk_combo_box_text_append(self.ptr, if (id) |i| i.ptr else null, text.ptr); 99 | } 100 | 101 | pub fn prepend(self: Self, id: ?[:0]const u8, text: [:0]const u8) void { 102 | c.gtk_combo_box_text_prepend(self.ptr, if (id) |i| i.ptr else null, text.ptr); 103 | } 104 | 105 | pub fn insert(self: Self, position: c_int, id: ?[:0]const u8, text: [:0]const u8) void { 106 | c.gtk_combo_box_text_append(self.ptr, position, if (id) |i| i.ptr else null, text.ptr); 107 | } 108 | 109 | pub fn append_text(self: Self, text: [:0]const u8) void { 110 | c.gtk_combo_box_append_text(self.ptr, text.ptr); 111 | } 112 | 113 | pub fn prepend_text(self: Self, text: [:0]const u8) void { 114 | c.gtk_combo_box_prepend_text(self.ptr, text.ptr); 115 | } 116 | 117 | pub fn insert_text(self: Self, position: c_int, text: [:0]const u8) void { 118 | c.gtk_combo_box_prepend_text(self.ptr, position, text.ptr); 119 | } 120 | 121 | pub fn remove(self: Self, position: c_int) void { 122 | c.gtk_combo_box_text_remove(self.ptr, position); 123 | } 124 | 125 | pub fn remove_all(self: Self) void { 126 | c.gtk_combo_box_remove_all(self.ptr); 127 | } 128 | 129 | pub fn get_active_text(self: Self, allocator: mem.Allocator) ?[:0]const u8 { 130 | const val = c.gtk_combo_box_text_get_active_text(self.ptr); 131 | defer c.g_free(@ptrCast(*c.gpointer, val)); 132 | const len = mem.len(val); 133 | return fmt.allocPrintZ(allocator, "{s}", .{val[0..len]}) catch return null; 134 | } 135 | 136 | pub fn as_combo_box(self: Self) ComboBox { 137 | return ComboBox{ 138 | .ptr = @ptrCast(*c.GtkComboBox, self.ptr), 139 | }; 140 | } 141 | 142 | pub fn as_widget(self: Self) Widget { 143 | return Widget{ 144 | .ptr = @ptrCast(*c.GtkWidget, self.ptr), 145 | }; 146 | } 147 | 148 | pub fn is_instance(gtype: u64) bool { 149 | return (gtype == c.gtk_combo_box_text_get_type()); 150 | } 151 | }; 152 | -------------------------------------------------------------------------------- /src/common.zig: -------------------------------------------------------------------------------- 1 | const c = @import("cimport.zig"); 2 | const enums = @import("enums.zig"); 3 | const Widget = @import("widget.zig").Widget; 4 | 5 | const std = @import("std"); 6 | const fmt = std.fmt; 7 | const mem = std.mem; 8 | 9 | /// The Gtk function g_signal_connect is defined in a macro which is unfortunately 10 | /// broken for translate-c, so we redefine the function doing what the orignal 11 | /// does internally as workaround. 12 | pub fn signal_connect(instance: c.gpointer, detailed_signal: [*c]const c.gchar, c_handler: c.GCallback, data: c.gpointer) c.gulong { 13 | var zero: u32 = 0; 14 | const flags: *c.GConnectFlags = @ptrCast(*c.GConnectFlags, &zero); 15 | return c.g_signal_connect_data(instance, detailed_signal, c_handler, data, null, flags.*); 16 | } 17 | 18 | /// Convenience function which returns a proper GtkWidget pointer or null 19 | pub fn builder_get_widget(builder: *c.GtkBuilder, name: [*]const u8) ?*c.GtkWidget { 20 | const obj = c.gtk_builder_get_object(builder, name); 21 | if (obj == null) { 22 | return null; 23 | } else { 24 | var gobject = @ptrCast([*c]c.GTypeInstance, obj); 25 | var gwidget = @ptrCast(*c.GtkWidget, c.g_type_check_instance_cast(gobject, c.gtk_widget_get_type())); 26 | return gwidget; 27 | } 28 | } 29 | 30 | /// Convenience function which returns a proper GtkAdjustment pointer or null 31 | pub fn builder_get_adjustment(builder: *c.GtkBuilder, name: [*]const u8) ?*c.GtkAdjustment { 32 | const obj = c.gtk_builder_get_object(builder, name); 33 | if (obj == null) { 34 | return null; 35 | } else { 36 | var gobject = @ptrCast([*c]c.GTypeInstance, obj); 37 | var adjustment = @ptrCast(*c.GtkAdjustment, gobject); 38 | return adjustment; 39 | } 40 | } 41 | 42 | /// Convenience function which returns a proper bool instead of 0 or 1 43 | pub fn toggle_button_get_active(but: *c.GtkToggleButton) bool { 44 | return (c.gtk_toggle_button_get_active(but) == 1); 45 | } 46 | 47 | /// Convenience function which takes a proper bool instead of 0 or 1 48 | pub fn widget_set_sensitive(widget: *c.GtkWidget, state: bool) void { 49 | c.gtk_widget_set_sensitive(widget, bool_to_c_int(state)); 50 | } 51 | 52 | /// Convenience function which takes a prope bool instead of 0 or 1 53 | pub fn widget_set_visible(widget: *c.GtkWidget, state: bool) void { 54 | c.gtk_widget_set_visible(widget, bool_to_c_int(state)); 55 | } 56 | 57 | /// Convenience function which takes a bool and returns a c_int 58 | pub fn bool_to_c_int(boolean: bool) c_int { 59 | return if (boolean) 1 else 0; 60 | } 61 | 62 | /// Convenience function which converts a GSlist singly-linked list to 63 | /// a Zig ArrayList 64 | pub fn gslistToArrayList(in: c.GSlist, allocator: mem.Allocator) ?std.ArrayList(Widget) { 65 | var list = std.ArrayList(Widget).init(allocator); 66 | while (in) |ptr| { 67 | list.append(Widget{ .ptr = @ptrCast(*c.GtkWidget, @alignCast(8, ptr.*.data)) }) catch { 68 | list.deinit(); 69 | return null; 70 | }; 71 | in = ptr.*.next; 72 | } 73 | return list; 74 | } 75 | -------------------------------------------------------------------------------- /src/container.zig: -------------------------------------------------------------------------------- 1 | const c = @import("cimport.zig"); 2 | const Box = @import("box.zig").Box; 3 | const Bin = @import("bin.zig").Bin; 4 | const Button = @import("button.zig").Button; 5 | const Expander = @import("expander.zig").Expander; 6 | const FlowBox = @import("flowbox.zig").FlowBox; 7 | const Frame = @import("frame.zig").Frame; 8 | const Grid = @import("grid.zig").Grid; 9 | const HeaderBar = @import("headerbar.zig").HeaderBar; 10 | const Notebook = @import("notebook.zig").Notebook; 11 | const Paned = @import("paned.zig").Paned; 12 | const stack = @import("stack.zig"); 13 | const Stack = stack.Stack; 14 | const StackSwitcher = stack.StackSwitcher; 15 | const StackSidebar = stack.StackSidebar; 16 | const Widget = @import("widget.zig").Widget; 17 | 18 | const std = @import("std"); 19 | const fmt = mem.fmt; 20 | const mem = std.mem; 21 | 22 | pub const Container = struct { 23 | ptr: *c.GtkContainer, 24 | 25 | const Self = @This(); 26 | 27 | pub fn add(self: Self, widget: Widget) void { 28 | c.gtk_container_add(self.ptr, widget.ptr); 29 | } 30 | 31 | pub fn remove(self: Self, widget: Widget) void { 32 | c.gtk_container_remove(self.ptr, widget.ptr); 33 | } 34 | 35 | pub fn check_resize(self: Self) void { 36 | c.gtk_container_check_resize(self.ptr); 37 | } 38 | 39 | pub fn foreach(self: Self, callback: *c.GtkCallback, data: c.gpointer) void { 40 | c.gtk_container_foreach(self.ptr, callback, data); 41 | } 42 | 43 | pub fn get_children(self: Self, allocator: mem.Allocator) ?std.ArrayList(Widget) { 44 | var kids = c.gtk_container_get_children(self.ptr); 45 | defer c.g_list_free(kids); 46 | var list = std.ArrayList(Widget).init(allocator); 47 | while (kids) |ptr| { 48 | list.append(Widget{ .ptr = @ptrCast(*c.GtkWidget, @alignCast(8, ptr.*.data)) }) catch { 49 | list.deinit(); 50 | return null; 51 | }; 52 | kids = ptr.*.next; 53 | } 54 | return list; 55 | } 56 | 57 | pub fn get_focus_child(self: Self) Widget { 58 | return Widget{ .ptr = c.gtk_container_get_focus_child(self.ptr) }; 59 | } 60 | 61 | pub fn set_focus_child(self: Self, child: Widget) void { 62 | c.gtk_widget_set_focus_child(self.ptr, child.ptr); 63 | } 64 | 65 | pub fn get_border_width(self: Self) c_uint { 66 | c.gtk_container_get_border_width(self.ptr); 67 | } 68 | 69 | pub fn set_border_width(self: Self, border: c_uint) void { 70 | c.gtk_container_set_border_width(self.ptr, border); 71 | } 72 | 73 | pub fn connect_add(self: Self, callback: c.GCallback, data: ?c.gpointer) void { 74 | self.as_widget().connect("add", callback, if (data) |d| d else null); 75 | } 76 | 77 | pub fn connect_check_resize(self: Self, callback: c.GCallback, data: ?c.gpointer) void { 78 | self.as_widget().connect("check-resize", callback, if (data) |d| d else null); 79 | } 80 | 81 | pub fn connect_remove(self: Self, callback: c.GCallback, data: ?c.gpointer) void { 82 | self.as_widget().connect("remove", callback, if (data) |d| d else null); 83 | } 84 | 85 | pub fn connect_set_focus_child(self: Self, callback: c.GCallback, data: ?c.gpointer) void { 86 | self.as_widget().connect("set-focus-child", callback, if (data) |d| d else null); 87 | } 88 | 89 | pub fn as_widget(self: Self) Widget { 90 | return Widget{ 91 | .ptr = @ptrCast(*c.GtkWidget, self.ptr), 92 | }; 93 | } 94 | 95 | pub fn is_instance(gtype: u64) bool { 96 | return (gtype == c.gtk_container_get_type() or Box.is_instance(gtype) or Grid.is_instance(gtype) or Notebook.is_instance(gtype) or Stack.is_instance(gtype)); 97 | } 98 | 99 | fn get_g_type(self: Self) u64 { 100 | return self.ptr.*.parent_instance.g_type_instance.g_class.*.g_type; 101 | } 102 | 103 | pub fn isa(self: Self, comptime T: type) bool { 104 | return T.is_instance(self.get_g_type()); 105 | } 106 | 107 | pub fn to_bin(self: Self) ?Bin { 108 | return if (self.isa(Bin)) Bin{ 109 | .ptr = @ptrCast(*c.GtkBin, self.ptr), 110 | } else null; 111 | } 112 | 113 | pub fn to_box(self: Self) ?Box { 114 | return if (self.isa(Box)) Box{ 115 | .ptr = @ptrCast(*c.GtkBox, self.ptr), 116 | } else null; 117 | } 118 | 119 | pub fn to_button(self: Self) ?Button { 120 | return if (self.isa(Button)) Button{ 121 | .ptr = @ptrCast(*c.GtkButton, self.ptr), 122 | } else null; 123 | } 124 | 125 | pub fn to_expander(self: Self) ?Expander { 126 | return if (self.isa(Expander)) Expander{ 127 | .ptr = @ptrCast(*c.GtkExpander, self.ptr), 128 | } else null; 129 | } 130 | 131 | pub fn to_flow_box(self: Self) ?FlowBox { 132 | return if (self.isa(FlowBox)) FlowBox{ 133 | .ptr = @ptrCast(*c.GtkFlowBox, self.ptr), 134 | } else null; 135 | } 136 | 137 | pub fn to_frame(self: Self) ?Frame { 138 | return if (self.isa(Frame)) Frame{ 139 | .ptr = @ptrCast(*c.GtkFrame, self.ptr), 140 | } else null; 141 | } 142 | 143 | pub fn to_grid(self: Self) ?Grid { 144 | return if (self.isa(Grid)) Grid{ 145 | .ptr = @ptrCast(*c.GtkGrid, self.ptr), 146 | } else null; 147 | } 148 | 149 | pub fn to_header_bar(self: Self) ?HeaderBar { 150 | return if (self.isa(HeaderBar)) HeaderBar{ 151 | .ptr = @ptrCast(*c.GtkHeaderBar, self.ptr), 152 | } else null; 153 | } 154 | 155 | pub fn to_notebook(self: Self) ?Notebook { 156 | return if (self.isa(Notebook)) Notebook{ 157 | .ptr = @ptrCast(*c.GtkNotebook, self.ptr), 158 | } else null; 159 | } 160 | 161 | pub fn to_paned(self: Self) ?Paned { 162 | return if (self.isa(Paned)) Paned{ 163 | .ptr = @ptrCast(*c.GtkPaned, self.ptr), 164 | } else null; 165 | } 166 | 167 | pub fn to_stack(self: Self) ?Stack { 168 | return if (self.isa(Stack)) Stack{ .ptr = @ptrCast(*c.GtkStack, self.ptr) } else null; 169 | } 170 | 171 | pub fn to_stack_switcher(self: Self) ?StackSwitcher { 172 | return if (self.isa(StackSwitcher)) StackSwitcher{ .ptr = @ptrCast(*c.GtkStackSwitcher, self.ptr) } else null; 173 | } 174 | 175 | pub fn to_stack_sidebar(self: Self) ?StackSidebar { 176 | return if (self.isa(StackSidebar)) StackSidebar{ .ptr = @ptrCast(*c.GtkStackSidebar, self.ptr) } else null; 177 | } 178 | }; 179 | -------------------------------------------------------------------------------- /src/convenience.zig: -------------------------------------------------------------------------------- 1 | usingnamespace @import("cimport.zig"); 2 | usingnamespace @import("enums.zig"); 3 | 4 | const std = @import("std"); 5 | const fmt = std.fmt; 6 | const mem = std.mem; 7 | 8 | /// The Gtk function g_signal_connect is defined in a macro which is unfortunately 9 | /// broken for translate-c, so we redefine the function doing what the orignal 10 | /// does internally as workaround. 11 | pub fn signal_connect(instance: gpointer, detailed_signal: [*c]const gchar, c_handler: GCallback, data: gpointer) gulong { 12 | var zero: u32 = 0; 13 | const flags: *GConnectFlags = @ptrCast(*GConnectFlags, &zero); 14 | return g_signal_connect_data(instance, detailed_signal, c_handler, data, null, flags.*); 15 | } 16 | 17 | /// Convenience function which returns a proper GtkWidget pointer or null 18 | pub fn builder_get_widget(builder: *GtkBuilder, name: [*]const u8) ?*GtkWidget { 19 | const obj = gtk_builder_get_object(builder, name); 20 | if (obj == null) { 21 | return null; 22 | } else { 23 | var gobject = @ptrCast([*c]GTypeInstance, obj); 24 | var gwidget = @ptrCast(*GtkWidget, g_type_check_instance_cast(gobject, gtk_widget_get_type())); 25 | return gwidget; 26 | } 27 | } 28 | 29 | /// Convenience function which returns a proper GtkAdjustment pointer or null 30 | pub fn builder_get_adjustment(builder: *GtkBuilder, name: [*]const u8) ?*GtkAdjustment { 31 | const obj = gtk_builder_get_object(builder, name); 32 | if (obj == null) { 33 | return null; 34 | } else { 35 | var gobject = @ptrCast([*c]GTypeInstance, obj); 36 | var adjustment = @ptrCast(*GtkAdjustment, gobject); 37 | return adjustment; 38 | } 39 | } 40 | 41 | /// Convenience function which returns a proper bool instead of 0 or 1 42 | pub fn toggle_button_get_active(but: *GtkToggleButton) bool { 43 | if (gtk_toggle_button_get_active(but) == 0) { 44 | return false; 45 | } else { 46 | return true; 47 | } 48 | } 49 | 50 | /// Convenience function which takes a proper bool instead of 0 or 1 51 | pub fn widget_set_sensitive(widget: *GtkWidget, state: bool) void { 52 | if (state) { 53 | gtk_widget_set_sensitive(widget, 1); 54 | } else { 55 | gtk_widget_set_sensitive(widget, 0); 56 | } 57 | } 58 | 59 | /// Convenience function which takes a prope bool instead of 0 or 1 60 | pub fn widget_set_visible(widget: *GtkWidget, state: bool) void { 61 | if (state) { 62 | gtk_widget_set_visible(widget, 1); 63 | } else { 64 | gtk_widget_set_visible(widget, 0); 65 | } 66 | } 67 | 68 | /// Convenience function which takes a bool and returns a c_int 69 | pub fn bool_to_c_int(boolean: bool) c_int { 70 | const val: c_int = if (boolean) 1 else 0; 71 | return val; 72 | } 73 | -------------------------------------------------------------------------------- /src/entry.zig: -------------------------------------------------------------------------------- 1 | const c = @import("cimport.zig"); 2 | 3 | const Button = @import("button.zig").Button; 4 | const Widget = @import("widget.zig").Widget; 5 | 6 | const std = @import("std"); 7 | const fmt = std.fmt; 8 | const mem = std.mem; 9 | 10 | pub const Entry = struct { 11 | ptr: *c.GtkEntry, 12 | 13 | pub fn new() Entry { 14 | return Entry{ 15 | .ptr = c.gtk_entry_new(), 16 | }; 17 | } 18 | 19 | pub fn new_with_buffer(buffer: EntryBuffer) Entry { 20 | return Entry{ 21 | .ptr = c.gtk_entry_new_with_buffer(buffer.ptr), 22 | }; 23 | } 24 | 25 | pub fn get_buffer(self: Entry) EntryBuffer { 26 | return EntryBuffer{ 27 | .ptr = c.gtk_entry_get_buffer(self.ptr), 28 | }; 29 | } 30 | 31 | pub fn set_buffer(self: Entry, buffer: EntryBuffer) void { 32 | c.gtk_entry_set_buffer(self.ptr, buffer.ptr); 33 | } 34 | 35 | pub fn set_text(self: Entry, text: [:0]const u8) void { 36 | c.gtk_entry_set_text(self.ptr, text.ptr); 37 | } 38 | 39 | pub fn get_text(self: Entry, allocator: mem.Allocator) ?[:0]const u8 { 40 | const val = c.gtk_entry_get_text(self.ptr); 41 | const len = mem.len(val); 42 | return fmt.allocPrintZ(allocator, "{s}", .{val[0..len]}) catch return null; 43 | } 44 | 45 | pub fn get_text_length(self: Entry) u16 { 46 | return @as(u16, c.gtk_entry_get_text_length(self.ptr)); 47 | } 48 | 49 | // not implemented get_text_area() 50 | 51 | pub fn set_visibility(self: Entry, visible: bool) void { 52 | c.gtk_entry_set_visibility(self.ptr, if (visible) 1 else 0); 53 | } 54 | 55 | // not implemented set_invisible_char() 56 | // not implemented unset_invisible_char() 57 | 58 | pub fn set_max_length(self: Entry, max: c_int) void { 59 | c.gtk_entry_set_max_length(self.ptr, max); 60 | } 61 | 62 | pub fn as_widget(self: Entry) Widget { 63 | return Widget{ 64 | .ptr = @ptrCast(*c.GtkWidget, self.ptr), 65 | }; 66 | } 67 | 68 | pub fn is_instance(gtype: u64) bool { 69 | return (gtype == c.gtk_entry_get_type()); 70 | } 71 | }; 72 | 73 | pub const EntryBuffer = struct { 74 | ptr: *c.GtkEntryBuffer, 75 | 76 | pub fn set_text(self: EntryBuffer, text: [:0]const u8, len: c_int) void { 77 | c.gtk_entry_buffer_set_text(self.ptr, text.ptr, len); 78 | } 79 | }; 80 | 81 | pub const EntryCompletion = struct { 82 | ptr: *c.GtkEntryCompletion, 83 | }; 84 | -------------------------------------------------------------------------------- /src/enums.zig: -------------------------------------------------------------------------------- 1 | const c = @import("cimport.zig"); 2 | 3 | /// Enum AccelFlags 4 | pub const AccelFlags = enum(c_uint) { 5 | visible = c.GTK_ACCEL_VISIBLE, 6 | locked = c.GTK_ACCEL_LOCKED, 7 | mask = c.GTK_ACCEL_MASK, 8 | }; 9 | 10 | /// enum ConnectFlags 11 | pub const ConnectFlags = enum(c_uint) { 12 | after = c.G_CONNECT_AFTER, 13 | swapped = c.G_CONNECT_SWAPPED, 14 | }; 15 | 16 | /// enum BaselinePosition 17 | pub const BaselinePosition = enum(c_uint) { 18 | top = c.GTK_BASELINE_POSITION_TOP, 19 | center = c.GTK_BASELINE_POSITION_CENTER, 20 | bottom = c.GTK_BASELINE_POSITION_BOTTOM, 21 | }; 22 | 23 | /// enum DeleteType 24 | pub const DeleteType = enum(c_uint) { 25 | chars = c.GTK_DELETE_CHARS, 26 | word_ends = c.GTK_DELETE_WORD_ENDS, 27 | words = c.GTK_DELETE_WORDS, 28 | line_ends = c.GTK_DELETE_LINE_ENDS, 29 | lines = c.GTK_DELETE_LINES, 30 | paragraph_ends = c.GTK_DELETE_PARAGRAPH_ENDS, 31 | paragraphs = c.GTK_DELETE_PARAGRAPHS, 32 | whitespace = c.GTK_DELETE_WHITESPACE, 33 | }; 34 | 35 | /// enum DirectionType 36 | pub const DirectionType = enum(c_uint) { 37 | forward = c.GTK_DIR_TAB_FORWARD, 38 | backward = c.GTK_DIR_TAB_BACKWARD, 39 | up = c.GTK_DIR_UP, 40 | down = c.GTK_DIR_DOWN, 41 | left = c.GTK_DIR_LEFT, 42 | right = c.GTK_DIR_RIGHT, 43 | }; 44 | 45 | /// enum IconSize 46 | pub const IconSize = enum(c_uint) { 47 | invalid = c.GTK_ICON_SIZE_INVALID, 48 | menu = c.GTK_ICON_SIZE_MENU, 49 | small_toolbar = c.GTK_ICON_SIZE_SMALL_TOOLBAR, 50 | large_toolbar = c.GTK_ICON_SIZE_LARGE_TOOLBAR, 51 | button = c.GTK_ICON_SIZE_BUTTON, 52 | dnd = c.GTK_ICON_SIZE_DND, 53 | dialog = c.GTK_ICON_SIZE_DIALOG, 54 | }; 55 | 56 | /// enum Justification 57 | pub const Justification = enum(c_uint) { 58 | left = c.GTK_JUSTIFY_LEFT, 59 | right = c.GTK_JUSTIFY_RIGHT, 60 | center = c.GTK_JUSTIFY_CENTER, 61 | fill = c.GTK_JUSTIFY_FILL, 62 | }; 63 | 64 | /// Enum License 65 | pub const License = enum(c_uint) { 66 | unknown = c.GTK_LICENSE_UNKNOWN, 67 | custon = c.GTK_LICENSE_CUSTOM, 68 | gpl2 = c.GTK_LICENSE_GPL_2_0, 69 | gtpl3 = c.GTK_LICENSE_GPL_3_0, 70 | lgpl2_1 = c.GTK_LICENSE_LGPL_2_1, 71 | lgpl3 = c.GTK_LICENSE_LGPL_3_0, 72 | bsd = c.GTK_LICENSE_BSD, 73 | mit_x11 = c.GTK_LICENSE_MIT_X11, 74 | artistic = c.GTK_LICENSE_ARTISTIC, 75 | gpl2_only = c.GTK_LICENSE_GPL_2_0_ONLY, 76 | gpl3_only = c.GTK_LICENSE_GPL_3_0_ONLY, 77 | lgpl2_1_only = c.GTK_LICENSE_LGPL_2_1_ONLY, 78 | lgpl3_only = c.GTK_LICENSE_LGPL_3_0_ONLY, 79 | agpl3 = c.GTK_LICENSE_AGPL_3_0, 80 | agpl3_only = c.GTK_LICENSE_AGPL_3_0_ONLY, 81 | bsd3 = c.GTK_LICENSE_BSD_3, 82 | apache2 = c.GTK_LICENSE_APACHE_2_0, 83 | mpl2 = c.GTK_LICENSE_MPL_2_0, 84 | }; 85 | 86 | /// Enum ModifierType 87 | pub const ModifierType = enum(c_uint) { 88 | shift_mask = c.GDK_SHIFT_MASK, 89 | mod1_mask = c.GDK_MOD1_MASK, 90 | control_mask = c.GDK_CONTROL_MASK, 91 | }; 92 | 93 | /// enum Orientation 94 | pub const Orientation = enum(c_uint) { 95 | horizontal = c.GTK_ORIENTATION_HORIZONTAL, 96 | vertical = c.GTK_ORIENTATION_VERTICAL, 97 | }; 98 | 99 | /// Enum PackType 100 | pub const PackType = enum(c_uint) { 101 | end = c.GTK_PACK_END, 102 | start = c.GTK_PACK_START, 103 | }; 104 | 105 | /// Enum PositionType 106 | pub const PositionType = enum(c_uint) { 107 | left = c.GTK_POS_LEFT, 108 | right = c.GTK_POS_RIGHT, 109 | top = c.GTK_POS_TOP, 110 | bottom = c.GTK_POS_BOTTOM, 111 | }; 112 | 113 | /// Enum ReliefStyle 114 | pub const ReliefStyle = enum(c_uint) { 115 | normal = c.GTK_RELIEF_NORMAL, 116 | none = c.GTK_RELIEF_NONE, 117 | }; 118 | 119 | /// Enum SelectionMode 120 | pub const SelectionMode = enum(c_uint) { 121 | none = c.GTK_SELECTION_NONE, 122 | single = c.GTK_SELECTION_SINGLE, 123 | browse = c.GTK_SELECTION_BROWSE, 124 | multiple = c.GTK_SELECTION_MULTIPLE, 125 | }; 126 | 127 | /// Enum SensitivityType 128 | pub const SensitivityType = enum(c_uint) { 129 | auto = c.GTK_SENSITIVITY_AUTO, 130 | on = c.GTK_SENSITIVITY_ON, 131 | off = c.GTK_SENSITIVITY_OFF, 132 | }; 133 | 134 | /// Used to change the appearance of an outline typically provided by a GtkFrame. 135 | /// 136 | /// Note that many themes do not differentiate the appearance of the various 137 | /// shadow types: Either their is no visible shadow (GTK_SHADOW_NONE ), or there 138 | /// is (any other value). 139 | pub const ShadowType = enum(c_uint) { 140 | none = c.GTK_SHADOW_NONE, 141 | in = c.GTK_SHADOW_IN, 142 | out = c.GTK_SHADOW_OUT, 143 | etched_in = c.GTK_SHADOW_ETCHED_IN, 144 | etched_out = c.GTK_SHADOW_ETCHED_OUT, 145 | }; 146 | 147 | /// enum SpawnFlags 148 | pub const SpawnFlags = enum(c_uint) { 149 | default = c.G_SPAWN_DEFAULT, 150 | leave_descriptors_open = c.G_SPAWN_LEAVE_DESCRIPTORS_OPEN, 151 | do_not_reap_child = c.G_SPAWN_DO_NOT_REAP_CHILD, 152 | search_path = c.G_SPAWN_SEARCH_PATH, 153 | stdout_to_dev_null = c.G_SPAWN_STDOUT_TO_DEV_NULL, 154 | stderr_to_dev_null = c.G_SPAWN_STDERR_TO_DEV_NULL, 155 | child_inherits_stdin = c.G_SPAWN_CHILD_INHERITS_STDIN, 156 | file_and_argv_zero = c.G_SPAWN_FILE_AND_ARGV_ZERO, 157 | search_path_from_envp = c.G_SPAWN_SEARCH_PATH_FROM_ENVP, 158 | cloexec_pipes = c.G_SPAWN_CLOEXEC_PIPES, 159 | }; 160 | 161 | /// Enum SpinButtonUpdatePolicy 162 | pub const SpinButtonUpdatePolicy = enum(c_uint) { 163 | always = c.GTK_UPDATE_ALWAYS, 164 | if_valid = c.GTK_UPDATE_IF_VALID, 165 | }; 166 | 167 | /// Enum SpinType 168 | pub const SpinType = enum(c_uint) { 169 | step_forward = c.GTK_SPIN_STEP_FORWARD, 170 | step_backward = c.GTK_SPIN_STEP_BACKWARD, 171 | page_forward = c.GTK_SPIN_PAGE_FORWARD, 172 | page_backward = c.GTK_SPIN_PAGE_BACKWARD, 173 | home = c.GTK_SPIN_HOME, 174 | end = c.GTK_SPIN_END, 175 | user_defined = c.GTK_SPIN_USER_DEFINED, 176 | }; 177 | 178 | /// enum WindowType 179 | pub const WindowType = enum(c_uint) { 180 | toplevel = c.GTK_WINDOW_TOPLEVEL, 181 | popup = c.GTK_WINDOW_POPUP, 182 | }; 183 | -------------------------------------------------------------------------------- /src/expander.zig: -------------------------------------------------------------------------------- 1 | const c = @import("cimport.zig"); 2 | const com = @import("common.zig"); 3 | const Bin = @import("bin.zig").Bin; 4 | const Container = @import("container.zig").Container; 5 | const Widget = @import("widget.zig").Widget; 6 | 7 | const std = @import("std"); 8 | const fmt = std.fmt; 9 | const mem = std.mem; 10 | 11 | pub const Expander = struct { 12 | ptr: *c.GtkExpander, 13 | 14 | const Self = @This(); 15 | 16 | pub fn new() Self { 17 | return Self{ 18 | .ptr = @ptrCast(*c.GtkExpander, c.gtk_expander_new()), 19 | }; 20 | } 21 | 22 | pub fn new_with_mnemonic(label: Widget) Self { 23 | return Self{ 24 | .ptr = @ptrCast(*c.GtkExpander, c.gtk_expander_new_with_mnemonic(label.ptr)), 25 | }; 26 | } 27 | 28 | pub fn set_expanded(self: Self, ex: bool) void { 29 | c.gtk_expander_set_expanded(self.ptr, if (ex) 1 else 0); 30 | } 31 | 32 | pub fn get_expanded(self: Self) bool { 33 | return (c.gtk_expander_get_expanded(self.ptr) == 1); 34 | } 35 | 36 | pub fn as_bin(self: Self) Bin { 37 | return Bin{ .ptr = @ptrCast(*c.GtkBin, self.ptr) }; 38 | } 39 | 40 | pub fn as_container(self: Self) Container { 41 | return Container{ 42 | .ptr = @ptrCast(*c.GtkContainer, self.ptr), 43 | }; 44 | } 45 | 46 | pub fn as_widget(self: Self) Widget { 47 | return Widget{ 48 | .ptr = @ptrCast(*c.GtkWidget, self.ptr), 49 | }; 50 | } 51 | 52 | pub fn is_instance(gtype: u64) bool { 53 | return (gtype == c.gtk_expander_get_type()); 54 | } 55 | }; 56 | -------------------------------------------------------------------------------- /src/filefilter.zig: -------------------------------------------------------------------------------- 1 | const c = @import("cimport.zig"); 2 | const Widget = @import("widget.zig").Widget; 3 | 4 | const std = @import("std"); 5 | const fmt = std.fmt; 6 | const mem = std.mem; 7 | 8 | pub const FileFilter = struct { 9 | ptr: *c.GtkFileFilter, 10 | 11 | const Self = @This(); 12 | 13 | pub const Flags = enum(c_uint) { 14 | filename = c.GTK_FILE_FILTER_FILENAME, 15 | uri = c.GTK_FILE_FILTER_URI, 16 | display_name = c.GTK_FILE_FILTER_DISPLAY_NAME, 17 | mime_type = c.GTK_FILE_FILTER_MIME_TYPE, 18 | }; 19 | 20 | pub fn new() Self { 21 | return Self{ .ptr = c.gtk_file_filter_new() }; 22 | } 23 | 24 | pub fn set_name(self: Self, name: [:0]const u8) void { 25 | c.gtk_file_filter_set_name(self.ptr, name.ptr); 26 | } 27 | 28 | pub fn get_name(self: Self, allocator: mem.Allocator) ?[:0]const u8 { 29 | const val = c.gtk_file_filter_get_name(self.ptr); 30 | const len = mem.len(val); 31 | return fmt.allocPrintZ(allocator, "{s}", .{val[0..len]}) catch return null; 32 | } 33 | 34 | pub fn add_mime_type(self: Self, mime: [:0]const u8) void { 35 | c.gtk_file_filter_add_mime_type(self.ptr, mime.ptr); 36 | } 37 | 38 | pub fn add_pattern(self: Self, pattern: [:0]const u8) void { 39 | c.gtk_file_filter_add_pattern(self.ptr, pattern.ptr); 40 | } 41 | 42 | pub fn add_pixbuf_formats(self: Self) void { 43 | c.gtk_file_filter_add_pixbuf_formats(self.ptr); 44 | } 45 | 46 | pub fn add_custom(self: Self, needed: Flags, func: c.GtkFileFilterFunc, data: c.gpointer, notify: c.GDestroyNotify) void { 47 | c.gtk_file_filter_add_custom(self.ptr, @enumToInt(needed), func, data, notify); 48 | } 49 | 50 | pub fn get_needed(self: Self) Flags { 51 | return @intToEnum(Flags, c.gtk_file_filter_get_needed(self.ptr)); 52 | } 53 | }; 54 | -------------------------------------------------------------------------------- /src/fixed.zig: -------------------------------------------------------------------------------- 1 | const c = @import("cimport.zig"); 2 | const Buildable = @import("buildable.zig").Buildable; 3 | const Container = @import("container.zig").Container; 4 | const Widget = @import("widget.zig").Widget; 5 | 6 | /// The GtkFixed widget is a container which can place child widgets at fixed 7 | /// positions and with fixed sizes, given in pixels. GtkFixed performs no 8 | /// automatic layout management. 9 | /// 10 | /// For most applications, you should not use this container! It keeps you from 11 | /// having to learn about the other GTK+ containers, but it results in broken 12 | /// applications. With GtkFixed, the following things will result in truncated 13 | /// text, overlapping widgets, and other display bugs: 14 | /// * Themes, which may change widget sizes. 15 | /// * Fonts other than the one you used to write the app will of course change the size of widgets containing text; keep in mind that users may use a larger font because of difficulty reading the default, or they may be using a different OS that provides different fonts. 16 | /// * Translation of text into other languages changes its size. Also, display of non-English text will use a different font in many cases. 17 | /// In addition, GtkFixed does not pay attention to text direction and thus may 18 | /// produce unwanted results if your app is run under right-to-left languages 19 | /// such as Hebrew or Arabic. That is: normally GTK+ will order containers 20 | /// appropriately for the text direction, e.g. to put labels to the right of the 21 | /// thing they label when using an RTL language, but it can’t do that with 22 | /// GtkFixed. So if you need to reorder widgets depending on the text direction, 23 | /// you would need to manually detect it and adjust child positions accordingly. 24 | /// 25 | /// Finally, fixed positioning makes it kind of annoying to add/remove GUI 26 | /// elements, since you have to reposition all the other elements. This is a 27 | /// long-term maintenance problem for your application. 28 | /// 29 | /// If you know none of these things are an issue for your application, and 30 | /// prefer the simplicity of GtkFixed, by all means use the widget. But you 31 | /// should be aware of the tradeoffs. 32 | /// 33 | /// See also GtkLayout, which shares the ability to perform fixed positioning 34 | /// of child widgets and additionally adds custom drawing and scrollability. 35 | pub const Fixed = struct { 36 | ptr: *c.GtkFixed, 37 | 38 | const Self = @This(); 39 | 40 | /// Creates a new GtkFixed. 41 | pub fn new() Self { 42 | return Self{ 43 | .ptr = @ptrCast(*c.GtkFixed, c.gtk_fixed_new()), 44 | }; 45 | } 46 | 47 | /// Adds a widget to a GtkFixed container at the given position. 48 | pub fn put(self: Self, child: Widget, x: c_int, y: c_int) void { 49 | c.gtk_fixed_put(self.ptr, child.ptr, x, y); 50 | } 51 | 52 | /// Moves a child of a GtkFixed container to the given position. 53 | pub fn move(self: Self, child: Widget, x: c_int, y: c_int) void { 54 | c.gtk_fixed_move(self.ptr, child.ptr, x, y); 55 | } 56 | 57 | pub fn as_buildable(self: Self) Buildable { 58 | return Buildable{ 59 | .ptr = @ptrCast(*c.GtkBuildable, self.ptr), 60 | }; 61 | } 62 | 63 | pub fn as_container(self: Self) Container { 64 | return Container{ 65 | .ptr = @ptrCast(*c.GtkContainer, self.ptr), 66 | }; 67 | } 68 | 69 | pub fn as_widget(self: Self) Widget { 70 | return Widget{ 71 | .ptr = @ptrCast(*c.GtkWidget, self.ptr), 72 | }; 73 | } 74 | 75 | pub fn is_instance(gtype: u64) bool { 76 | return (gtype == c.gtk_fixed_get_type()); 77 | } 78 | }; 79 | -------------------------------------------------------------------------------- /src/flowbox.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const mem = std.mem; 3 | const c = @import("cimport.zig"); 4 | const Adjustment = @import("adjustment.zig"); 5 | const Container = @import("container.zig").Container; 6 | const SelectionMode = @import("enums.zig").SelectionMode; 7 | 8 | const Orientable = @import("orientable.zig").Orientable; 9 | const Widget = @import("widget.zig").Widget; 10 | 11 | const FlowBox = struct { 12 | ptr: *c.GtkFlowBox, 13 | 14 | const Self = @This(); 15 | 16 | pub fn new() Self { 17 | return Self{ .ptr = @ptrCast(*c.GtkFlowBox, c.gtk_flow_box_new()) }; 18 | } 19 | 20 | pub fn insert(self: Self, child: Widget, pos: c_int) void { 21 | c.gtk_flow_box_insert(self.ptr, child.ptr, pos); 22 | } 23 | 24 | pub fn get_child_at_index(self: Self, idx: c_int) ?FlowBoxChild { 25 | return if (c.gtk_flow_box_get_child_at_index(self.ptr, idx)) |child| 26 | FlowBoxChild{ .ptr = child } 27 | else 28 | null; 29 | } 30 | 31 | pub fn get_child_at_pos(self: Self, x: c_int, y: c_int) ?FlowBoxChild { 32 | return if (c.gtk_flow_box_get_child_at_pos(self.ptr, x, y)) |child| 33 | FlowBoxChild{ .ptr = child } 34 | else 35 | null; 36 | } 37 | 38 | pub fn set_hadjustment(self: Self, adjustment: Adjustment) void { 39 | c.gtk_flow_box_set_hadjustment(self.ptr, adjustment.ptr); 40 | } 41 | 42 | pub fn set_vadjustment(self: Self, adjustment: Adjustment) void { 43 | c.gtk_flow_box_set_vadjustment(self.ptr, adjustment.ptr); 44 | } 45 | 46 | pub fn set_homogeneous(self: Self, hom: bool) void { 47 | c.gtk_flow_box_set_homogeneous(self.ptr, if (hom) 1 else 0); 48 | } 49 | 50 | pub fn get_homogeneous(self: Self) bool { 51 | return (c.gtk_flow_box_get_homogeneous(self.ptr) == 1); 52 | } 53 | 54 | pub fn set_row_spacing(self: Self, spacing: c_uint) void { 55 | c.gtk_flow_box_set_row_spacing(self.ptr, spacing); 56 | } 57 | 58 | pub fn get_row_spacing(self: Self) c_uint { 59 | return c.gtk_flow_box_get_row_spacing(self.ptr); 60 | } 61 | 62 | pub fn set_column_spacing(self: Self, spacing: c_uint) void { 63 | c.gtk_flow_box_set_column_spacing(self.ptr, spacing); 64 | } 65 | 66 | pub fn get_column_spacing(self: Self) c_uint { 67 | return c.gtk_flow_box_get_column_spacing(self.ptr); 68 | } 69 | 70 | pub fn set_min_children_per_line(self: Self, min: c_uint) void { 71 | c.gtk_flow_box_set_min_children_pre_line(self.ptr, min); 72 | } 73 | 74 | pub fn get_min_children_per_line(self: Self) c_uint { 75 | return c.gtk_flow_box_get_min_children_per_line(self.ptr); 76 | } 77 | 78 | pub fn set_max_children_per_line(self: Self, min: c_uint) void { 79 | c.gtk_flow_box_set_max_children_pre_line(self.ptr, min); 80 | } 81 | 82 | pub fn get_max_children_per_line(self: Self) c_uint { 83 | return c.gtk_flow_box_get_max_children_per_line(self.ptr); 84 | } 85 | 86 | pub fn set_activate_on_single_click(self: Self, single: bool) void { 87 | c.gtk_flow_box_set_activate_on_single_click(self.ptr, if (single) 1 else 0); 88 | } 89 | 90 | pub fn get_activate_on_single_click(self: Self) bool { 91 | return (c.gtk_flow_box_get_activate_on_single_click(self.ptr) == 1); 92 | } 93 | 94 | pub fn selected_foreach(self: Self, func: *c.GtkFlowBoxForeachFunc, data: ?c.gpointer) void { 95 | c.gtk_flow_box_selected_foreach(self.ptr, func, if (data) |d| d else null); 96 | } 97 | 98 | pub fn get_selected_children(self: Self, allocator: mem.Allocator) ?std.ArrayList(Widget) { 99 | var kids = c.gtk_flow_box_get_selected_children(self.ptr); 100 | defer c.g_list_free(kids); 101 | var list = std.ArrayList(Widget).init(allocator); 102 | while (kids) |ptr| { 103 | list.append(Widget{ .ptr = @ptrCast(*c.GtkWidget, @alignCast(8, ptr.*.data)) }) catch { 104 | list.deinit(); 105 | return null; 106 | }; 107 | kids = ptr.*.next; 108 | } 109 | return list; 110 | } 111 | 112 | pub fn select_child(self: Self, child: FlowBoxChild) void { 113 | c.gtk_flow_box_select_child(self.ptr, child.ptr); 114 | } 115 | 116 | pub fn unselect_child(self: Self, child: FlowBoxChild) void { 117 | c.gtk_flow_box_unselect_child(self.ptr, child.ptr); 118 | } 119 | 120 | pub fn select_all(self: Self) void { 121 | c.gtk_flow_box_select_all(self.ptr); 122 | } 123 | 124 | pub fn unselect_all(self: Self) void { 125 | c.gtk_flow_box_unselect_all(self.ptr); 126 | } 127 | 128 | pub fn set_selection_mode(self: Self, mode: SelectionMode) void { 129 | c.gtk_flow_box_swet_selection_mode(self.ptr, @enumToInt(mode)); 130 | } 131 | 132 | pub fn get_selection_mode(self: Self) SelectionMode { 133 | return @intToEnum(SelectionMode, c.gtk_flow_box_get_selection_mode(self.ptr)); 134 | } 135 | 136 | pub fn set_filter_func( 137 | self: Self, 138 | func: *c.GtkFlowBoxFilterFunc, 139 | data: ?c.gpointer, 140 | destroy: c.GDestroyNotify, 141 | ) void { 142 | c.gtk_flow_box_set_filter_func(self.ptr, func, if (data) |d| d else null, destroy); 143 | } 144 | 145 | pub fn invalidate_filter(self: Self) void { 146 | c.gtk_flow_box_invalidate_filter(self.ptr); 147 | } 148 | 149 | pub fn set_sort_func( 150 | self: Self, 151 | func: *c.GtkFlowBoxSortFunc, 152 | data: ?c.gpointer, 153 | destroy: c.GDestroyNotify, 154 | ) void { 155 | c.gtk_flow_box_set_sort_func(self.ptr, func, if (data) |d| d else null, destroy); 156 | } 157 | 158 | pub fn invalidate_sort(self: Self) void { 159 | c.gtk_flow_box_invalidate_sort(self.ptr); 160 | } 161 | 162 | pub fn bind_model( 163 | self: Self, 164 | model: *c.GListModel, 165 | func: *c.GtkFlowBoxCreateWidgetFunc, 166 | data: ?c.gpointer, 167 | free_func: c.GDestroyNotify, 168 | ) void { 169 | c.gtk_flow_box_bind_model(self.ptr, model, func, if (data) |d| d else null, free_func); 170 | } 171 | 172 | pub fn as_container(self: Self) Container { 173 | return Container{ 174 | .ptr = @ptrCast(*c.GtkContainer, self.ptr), 175 | }; 176 | } 177 | 178 | pub fn as_orientable(self: Self) Orientable { 179 | return Orientable{ 180 | .ptr = @ptrCast(*c.GtkOrientable, self.ptr), 181 | }; 182 | } 183 | 184 | pub fn as_widget(self: Self) Widget { 185 | return Widget{ 186 | .ptr = @ptrCast(*c.GtkWidget, self.ptr), 187 | }; 188 | } 189 | 190 | pub fn is_instance(gtype: u64) bool { 191 | return (gtype == c.gtk_flow_box_get_type()); 192 | } 193 | }; 194 | 195 | const FlowBoxChild = struct { 196 | ptr: *c.GtkFlowBoxChild, 197 | 198 | const Self = @This(); 199 | 200 | pub fn new() Self { 201 | return Self{ 202 | .ptr = @ptrCast(*c.GtkFlowBoxChild, c.gtk_flow_box_child_new()), 203 | }; 204 | } 205 | 206 | pub fn get_index(self: Self) c_int { 207 | return c.gtk_flow_box_child_get_index(self.ptr); 208 | } 209 | 210 | pub fn is_selected(self: Self) bool { 211 | return (c.gtk_flow_box_child_is_selected(self.ptr) == 1); 212 | } 213 | 214 | pub fn changed(self: Self) void { 215 | c.gtk_flow_box_child_changed(self.ptr); 216 | } 217 | 218 | pub fn as_widget(self: Self) Widget { 219 | return Widget{ 220 | .ptr = @ptrCast(*c.GtkWidget, self.ptr), 221 | }; 222 | } 223 | 224 | pub fn is_instance(gtype: u64) bool { 225 | return (gtype == c.gtk_flow_box_child_get_type()); 226 | } 227 | }; 228 | -------------------------------------------------------------------------------- /src/fontchooser.zig: -------------------------------------------------------------------------------- 1 | const c = @import("cimport.zig"); 2 | const common = @import("common.zig"); 3 | 4 | const Actionable = @import("actionable.zig").Actionable; 5 | const Dialog = @import("dialog.zig").Dialog; 6 | const Widget = @import("widget.zig").Widget; 7 | 8 | const std = @import("std"); 9 | const fmt = std.fmt; 10 | const mem = std.mem; 11 | 12 | pub const FontChooser = struct { 13 | ptr: *c.GtkFontChooser, 14 | 15 | const Self = @This(); 16 | 17 | pub fn get_font_family(self: Self) ?*c.PangoFontFamily { 18 | return if (c.gtk_font_chooser_get_font_family(self.ptr)) |f| f else null; 19 | } 20 | 21 | pub fn get_font_face(self: Self) ?*c.PangoFontFace { 22 | return if (c.gtk_font_chooser_get_font_face(self.ptr)) |f| f else null; 23 | } 24 | 25 | pub fn get_font_size(self: Self) ?c_int { 26 | const s = c.gtk_font_chooser_get_font_size(self.ptr); 27 | return if (s == -1) null else s; 28 | } 29 | 30 | pub fn get_font(self: Self, allocator: mem.Allocator) ?[:0]const u8 { 31 | if (c.gtk_font_chooser_get_font(self.ptr)) |val| { 32 | const len = mem.len(val); 33 | return fmt.allocPrintZ(allocator, "{s}", .{val[0..len]}) catch return null; 34 | } else return null; 35 | } 36 | 37 | pub fn set_font(self: Self, font: [:0]const u8) void { 38 | c.gtk_font_chooser_set_font(self.ptr, font.ptr); 39 | } 40 | 41 | pub fn get_font_desc(self: Self) ?*c.PangoFontDescription { 42 | return if (c.gtk_font_chooser_get_font_desc(self.ptr)) |d| d else null; 43 | } 44 | 45 | pub fn set_font_desc(self: Self, desc: *c.PangoFontDescription) void { 46 | c.gtk_font_chooser_set_font_desc(self.ptr, desc); 47 | } 48 | 49 | pub fn get_preview_text(self: Self, allocator: mem.Allocator) ?[:0]const u8 { 50 | if (c.gtk_font_chooser_get_preview_text(self.ptr)) |val| { 51 | const len = mem.len(val); 52 | return fmt.allocPrintZ(allocator, "{s}", .{val[0..len]}) catch return null; 53 | } else return null; 54 | } 55 | 56 | pub fn set_preview_text(self: Self, text: [:0]const u8) void { 57 | c.gtk_font_chooser_set_preview_text(self.ptr, text.ptr); 58 | } 59 | 60 | pub fn get_show_preview_entry(self: Self) bool { 61 | return (c.gtk_font_chooser_get_show_preview_entry(self.ptr) == 1); 62 | } 63 | 64 | pub fn set_show_preview_entry(self: Self, show: bool) void { 65 | c.gtk_font_chooser_set_show_preview_entry(self.ptr, if (show) 1 else 0); 66 | } 67 | 68 | pub fn set_font_map(self: Self, map: *c.PangoFontMap) void { 69 | c.gtk_font_chooser_set_font_map(self.ptr, map); 70 | } 71 | 72 | pub fn as_widget(self: Self) Widget { 73 | return Widget{ 74 | .ptr = @ptrCast(*c.GtkWidget, self.ptr), 75 | }; 76 | } 77 | 78 | pub fn to_font_button(self: Self) ?FontButton { 79 | return if (self.as_widget().isa(FontButton)) FontButton{ 80 | .ptr = @ptrCast(*c.GtkFontButton, self.ptr), 81 | } else null; 82 | } 83 | 84 | pub fn to_font_chooser_widget(self: Self) ?FontChooserWidget { 85 | return if (self.as_widget().isa(FontChooserWidget)) FontChooserWidget{ 86 | .ptr = @ptrCast(*c.GtkFontChooserWidget, self.ptr), 87 | } else null; 88 | } 89 | 90 | pub fn to_font_chooser_dialog(self: Self) ?FontChooserDialog { 91 | return if (self.as_widget().isa(FontChooserDialog)) FontChooserDialog{ 92 | .ptr = @ptrCast(*c.GtkFontChooserDialog, self.ptr), 93 | } else null; 94 | } 95 | 96 | pub fn is_instance(gtype: u64) bool { 97 | return (gtype == c.gtk_font_chooser_get_type() or FontButton.is_instance(gtype) or FontChooserWidget.is_instance(gtype) or FontChooserDialog.is_instance(gtype)); 98 | } 99 | }; 100 | 101 | pub const FontButton = struct { 102 | ptr: *c.GtkFontButton, 103 | 104 | const Self = @This(); 105 | 106 | pub fn new() Self { 107 | return Self{ 108 | .ptr = @ptrCast(*c.GtkFontButton, c.gtk_font_button_new()), 109 | }; 110 | } 111 | 112 | pub fn new_with_font(name: [:0]const u8) Self { 113 | return Self{ 114 | .ptr = @ptrCast(*c.GtkGontButton, c.gtk_font_button_new_with_font(name.ptr)), 115 | }; 116 | } 117 | 118 | pub fn set_show_style(self: Self, show: bool) void { 119 | c.gtk_font_button_set_show_style(self.ptr, if (show) 1 else 0); 120 | } 121 | 122 | pub fn get_show_style(self: Self) bool { 123 | return (c.gtk_font_button_get_show_style(self.ptr) == 1); 124 | } 125 | 126 | pub fn set_show_size(self: Self, show: bool) void { 127 | c.gtk_font_button_set_show_size(self.ptr, if (show) 1 else 0); 128 | } 129 | 130 | pub fn get_show_size(self: Self) bool { 131 | return (c.gtk_font_button_get_show_size(self.ptr) == 1); 132 | } 133 | 134 | pub fn set_use_font(self: Self, use: bool) void { 135 | c.gtk_font_button_set_use_font(self.ptr, if (use) 1 else 0); 136 | } 137 | 138 | pub fn get_use_font(self: Self) bool { 139 | return (c.gtk_font_button_get_use_font(self.ptr) == 1); 140 | } 141 | 142 | pub fn set_use_size(self: Self, use: bool) void { 143 | c.gtk_font_button_set_use_size(self.ptr, if (use) 1 else 0); 144 | } 145 | 146 | pub fn get_use_size(self: Self) bool { 147 | return (c.gtk_font_button_get_use_size(self.ptr) == 1); 148 | } 149 | 150 | pub fn set_title(self: Self, title: [:0]const u8) void { 151 | c.gtk_font_button_set_title(self.ptr, title.ptr); 152 | } 153 | 154 | pub fn get_title(self: Self, allocator: mem.Allocator) ?[:0]const u8 { 155 | if (c.gtk_font_button_get_title(self.ptr)) |val| { 156 | const len = mem.len(val); 157 | return fmt.allocPrintZ(allocator, "{s}", .{val[0..len]}) catch return null; 158 | } else return null; 159 | } 160 | 161 | pub fn as_actionable(self: Self) Actionable { 162 | return Actionable{ 163 | .ptr = @ptrCast(*c.GtkActionable, self.ptr), 164 | }; 165 | } 166 | 167 | pub fn as_font_chooser(self: Self) FontChooser { 168 | return FontChooser{ 169 | .ptr = @ptrCast(*c.GtkFontChooser, self.ptr), 170 | }; 171 | } 172 | 173 | pub fn as_widget(self: Self) Widget { 174 | return Widget{ 175 | .ptr = @ptrCast(*c.GtkWidget, self.ptr), 176 | }; 177 | } 178 | 179 | pub fn is_instance(gtype: u64) bool { 180 | return (gtype == c.gtk_font_button_get_type()); 181 | } 182 | }; 183 | 184 | pub const FontChooserWidget = struct { 185 | ptr: *c.GtkFontChooserWidget, 186 | 187 | const Self = @This(); 188 | 189 | pub fn new() Self { 190 | return Self{ 191 | .ptr = @ptrCast(*c.GtkFontChooserWidget, c.gtk_font_chooser_widget_new()), 192 | }; 193 | } 194 | 195 | pub fn as_widget(self: Self) Widget { 196 | return Widget{ 197 | .ptr = @ptrCast(*c.GtkWidget, self.ptr), 198 | }; 199 | } 200 | 201 | pub fn as_font_chooser(self: Self) Widget { 202 | return FontChooser{ 203 | .ptr = @ptrCast(*c.GtkFontChooser, self.ptr), 204 | }; 205 | } 206 | 207 | pub fn is_instance(gtype: u64) bool { 208 | return (gtype == c.gtk_font_chooser_widget_get_type()); 209 | } 210 | }; 211 | 212 | pub const FontChooserDialog = struct { 213 | ptr: *c.GtkFontChooserDialog, 214 | 215 | const Self = @This(); 216 | 217 | pub fn new() Self { 218 | return Self{ 219 | .ptr = @ptrCast(*c.GtkFontChooserDialog, c.gtk_font_chooser_dialog_new()), 220 | }; 221 | } 222 | 223 | pub fn as_dialog(self: Self) Dialog { 224 | return Dialog{ 225 | .ptr = @ptrCast(*c.GtkDialog, self.ptr), 226 | }; 227 | } 228 | 229 | pub fn as_font_chooser(self: Self) Widget { 230 | return FontChooser{ 231 | .ptr = @ptrCast(*c.GtkFontChooser, self.ptr), 232 | }; 233 | } 234 | 235 | pub fn as_widget(self: Self) Widget { 236 | return Widget{ 237 | .ptr = @ptrCast(*c.GtkWidget, self.ptr), 238 | }; 239 | } 240 | 241 | pub fn is_instance(gtype: u64) bool { 242 | return (gtype == c.gtk_font_chooser_dialog_get_type()); 243 | } 244 | }; 245 | -------------------------------------------------------------------------------- /src/frame.zig: -------------------------------------------------------------------------------- 1 | const c = @import("cimport.zig"); 2 | 3 | const Bin = @import("bin.zig").Bin; 4 | const Buildable = @import("buildable.zig").Buildable; 5 | const Container = @import("container.zig").Container; 6 | const ShadowType = @import("enums.zig").ShadowType; 7 | const Widget = @import("widget.zig").Widget; 8 | 9 | const std = @import("std"); 10 | const fmt = std.fmt; 11 | const mem = std.mem; 12 | 13 | /// # Description 14 | /// The frame widget is a bin that surrounds its child with a decorative frame 15 | /// and an optional label. If present, the label is drawn in a gap in the top 16 | /// side of the frame. The position of the label can be controlled with 17 | /// Frame.set_label_align(). 18 | /// ### Frame as Buildable 19 | /// The GtkFrame implementation of the GtkBuildable interface supports placing a 20 | /// child in the label position by specifying “label” as the “type” attribute of 21 | /// a element. A normal content child can be specified without 22 | /// specifying a type attribute. 23 | /// ```XML 24 | /// 25 | /// 26 | /// 27 | /// 28 | /// 29 | /// 30 | /// 31 | /// 32 | /// ``` 33 | /// ### CSS 34 | /// GtkFrame has a main CSS node named “frame” and a subnode named “border”. The 35 | /// “border” node is used to draw the visible border. You can set the appearance 36 | /// of the border using CSS properties like “border-style” on the “border” node. 37 | /// 38 | /// The border node can be given the style class “.flat”, which is used by 39 | /// themes to disable drawing of the border. To do this from code, call 40 | /// Frame.set_shadow_type() with ShadowType.none to add the “.flat” class or any 41 | /// other shadow type to remove it. 42 | pub const Frame = struct { 43 | ptr: *c.GtkFrame, 44 | 45 | const Self = @This(); 46 | 47 | const Align = struct { 48 | x: f32, 49 | y: f32, 50 | }; 51 | 52 | /// Creates a new GtkFrame, with optional label label . If label is `null`, 53 | /// the label is omitted. 54 | pub fn new(label: ?[:0]const u8) Self { 55 | return Self{ 56 | .ptr = @ptrCast(*c.GtkFrame, c.gtk_frame_new(if (label) |l| l.ptr else null)), 57 | }; 58 | } 59 | 60 | /// Removes the current “label-widget”. If label is not `null`, creates a 61 | /// new GtkLabel with that text and adds it as the “label-widget”. 62 | pub fn set_label(self: Self, label: ?[:0]const u8) void { 63 | c.gtk_frame_set_label(self.ptr, if (label) |l| l.ptr else null); 64 | } 65 | 66 | /// Sets the “label-widget” for the frame. This is the widget that will 67 | /// appear embedded in the top edge of the frame as a title. 68 | pub fn set_label_widget(self: Self, widget: Widget) void { 69 | c.gtk_frame_set_label_widget(self.ptr, widget.ptr); 70 | } 71 | 72 | /// Sets the alignment of the frame widget’s label. The default values for a 73 | /// newly created frame are 0.0 and 0.5. 74 | pub fn set_label_align(self: Self, x: f32, y: f32) void { 75 | c.gtk_frame_set_label_align(self.ptr, x, y); 76 | } 77 | 78 | /// Sets the “shadow-type” for frame , i.e. whether it is drawn without 79 | /// (ShadowType.none) or with (other values) a visible border. Values other 80 | /// than ShadowType.none are treated identically by GtkFrame. The chosen 81 | /// type is applied by removing or adding the .flat class to the CSS node 82 | /// named border. 83 | pub fn set_shadow_type(self: Self, shadow: ShadowType) void { 84 | c.gtk_frame_set_shadow_type(self.ptr, @enumToInt(shadow)); 85 | } 86 | 87 | /// If the frame’s label widget is a GtkLabel, returns the text in the label 88 | /// widget. (The frame will have a GtkLabel for the label widget if a 89 | /// non-NULL argument was passed to gtk_frame_new().) 90 | pub fn get_label(self: Self, allocator: mem.Allocator) ?[:0]const u8 { 91 | const val = c.gtk_frame_get_label(self.ptr); 92 | if (val) |v| { 93 | const len = mem.len(val); 94 | return fmt.allocPrintZ(allocator, "{s}", .{v[0..len]}) catch { 95 | return null; 96 | }; 97 | } else return null; 98 | } 99 | 100 | /// Retrieves the X and Y alignment of the frame’s label. See 101 | /// Frame.set_label_align(). 102 | pub fn get_label_align(self: Self) Align { 103 | var x: f32 = undefined; 104 | var y: f32 = undefined; 105 | c.gtk_frame_get_label_align(self.ptr, x, y); 106 | return Align{ .x = x, .y = y }; 107 | } 108 | 109 | /// Retrieves the label widget for the frame. See Frame.set_label_widget(). 110 | pub fn get_label_widget(self: Self) ?Widget { 111 | return if (c.gtk_frame_get_label_widget(self.ptr)) |w| Widget{ .ptr = w } else null; 112 | } 113 | 114 | /// Retrieves the shadow type of the frame. See Frame.set_shadow_type(). 115 | pub fn get_shadow_type(self: Self) ShadowType { 116 | return @intToEnum(ShadowType, c.gtk_frame_get_shadow_type(self.ptr)); 117 | } 118 | 119 | pub fn is_instance(gtype: u64) bool { 120 | return (gtype == c.gtk_frame_get_type()); 121 | } 122 | 123 | pub fn as_bin(self: Self) Bin { 124 | return Bin{ .ptr = @ptrCast(*c.GtkBin, self.ptr) }; 125 | } 126 | 127 | pub fn as_buildable(self: Self) Buildable { 128 | return Buildable{ .ptr = @ptrCast(*c.GtkBuildable, self.ptr) }; 129 | } 130 | 131 | pub fn as_container(self: Self) Container { 132 | return Container{ .ptr = @ptrCast(*c.GtkContainer, self.ptr) }; 133 | } 134 | 135 | pub fn as_widget(self: Self) Widget { 136 | return Widget{ .ptr = @ptrCast(*c.GtkWidget, self.ptr) }; 137 | } 138 | }; 139 | 140 | /// The AspectFrame is useful when you want pack a widget so that it can resize 141 | /// but always retains the same aspect ratio. For instance, one might be drawing 142 | /// a small preview of a larger image. AspectFrame derives from Frame, so it can 143 | /// draw a label and a frame around the child. The frame will be “shrink-wrapped” 144 | /// to the size of the child. 145 | /// ### CSS 146 | /// GtkAspectFrame uses a CSS node with name frame. 147 | pub const AspectFrame = struct { 148 | ptr: *c.GtkAspectFrame, 149 | 150 | const Self = @This(); 151 | 152 | /// Create a new GtkAspectFrame. 153 | pub fn new( 154 | /// Label text. 155 | label: [:0]const u8, 156 | /// Horizontal alignment of the child within the allocation of the 157 | /// AspectFrame. This ranges from 0.0 (left aligned) to 1.0 (right aligned) 158 | xalign: f32, 159 | /// Vertical alignment of the child within the allocation of the 160 | /// AspectFrame. This ranges from 0.0 (top aligned) to 1.0 (bottom aligned) 161 | yalign: f32, 162 | /// The desired aspect ratio. 163 | ratio: f32, 164 | /// If true, ratio is ignored, and the aspect ratio is taken from the 165 | /// requistion of the child. 166 | obey_child: bool, 167 | ) Self { 168 | return Self{ .ptr = @ptrCast( 169 | *c.GtkAspectFrame, 170 | c.gtk_aspect_frame_new(label.ptr, xalign, yalign, ratio, if (obey_child) 1 else 0), 171 | ) }; 172 | } 173 | 174 | /// Set parameters for an existing GtkAspectFrame. 175 | pub fn set( 176 | self: Self, 177 | /// Horizontal alignment of the child within the allocation of the 178 | /// AspectFrame. This ranges from 0.0 (left aligned) to 1.0 (right aligned) 179 | xalign: f32, 180 | /// Vertical alignment of the child within the allocation of the 181 | /// AspectFrame. This ranges from 0.0 (top aligned) to 1.0 (bottom aligned) 182 | yalign: f32, 183 | /// The desired aspect ratio. 184 | ratio: f32, 185 | /// If true, ratio is ignored, and the aspect ratio is taken from the 186 | /// requistion of the child. 187 | obey_child: bool, 188 | ) void { 189 | c.gtk_aspect_frame_set(self.ptr, xalign, yalign, ratio, if (obey_child) 1 else 0); 190 | } 191 | 192 | pub fn is_instance(gtype: u64) bool { 193 | return (gtype == c.gtk_aspect_frame_get_type()); 194 | } 195 | 196 | pub fn as_bin(self: Self) Bin { 197 | return Bin{ .ptr = @ptrCast(*c.GtkBin, self.ptr) }; 198 | } 199 | 200 | pub fn as_buildable(self: Self) Buildable { 201 | return Buildable{ .ptr = @ptrCast(*c.GtkBuildable, self.ptr) }; 202 | } 203 | 204 | pub fn as_container(self: Self) Container { 205 | return Container{ .ptr = @ptrCast(*c.GtkContainer, self.ptr) }; 206 | } 207 | 208 | pub fn as_frame(self: Self) Frame { 209 | return Frame{ .ptr = @ptrCast(*c.GtkFrame, self.ptr) }; 210 | } 211 | 212 | pub fn as_widget(self: Self) Widget { 213 | return Widget{ .ptr = @ptrCast(*c.GtkWidget, self.ptr) }; 214 | } 215 | }; 216 | -------------------------------------------------------------------------------- /src/grid.zig: -------------------------------------------------------------------------------- 1 | const c = @import("cimport.zig"); 2 | const enums = @import("enums.zig"); 3 | const BaselinePosition = enums.BaselinePosition; 4 | const Buildable = @import("buildable.zig").Buildable; 5 | const Container = @import("container.zig").Container; 6 | const Orientable = @import("orientable.zig").Orientable; 7 | const PositionType = enums.PositionType; 8 | const Widget = @import("widget.zig").Widget; 9 | 10 | const std = @import("std"); 11 | const fmt = std.fmt; 12 | const mem = std.mem; 13 | 14 | pub const Grid = struct { 15 | ptr: *c.GtkGrid, 16 | 17 | const Self = @This(); 18 | 19 | pub fn new() Self { 20 | return Self{ 21 | .ptr = c.gtk_grid_new(), 22 | }; 23 | } 24 | 25 | pub fn attach(self: Self, child: Widget, left: c_int, top: c_int, width: c_int, height: c_int) void { 26 | c.gtk_grid_attach(self.ptr, child.ptr, left, top, width, height); 27 | } 28 | 29 | pub fn attach_next_to(self: Self, child: Widget, sibling: Widget, side: PositionType, width: c_int, height: c_int) void { 30 | c.gtk_grid_attach_next_to(self.ptr, child.ptr, sibling.ptr, @enumToInt(side), width, height); 31 | } 32 | 33 | pub fn get_child_at(self: Self, left: c_int, top: c_int) ?Widget { 34 | const val = c.gtk_grid_get_child_at(self.ptr, left, top); 35 | return if (val) |v| Widget{ 36 | .ptr = v, 37 | } else null; 38 | } 39 | 40 | pub fn insert_row(self: Self, position: c_int) void { 41 | c.gtk_grid_insert_row(self.ptr, position); 42 | } 43 | 44 | pub fn insert_column(self: Self, position: c_int) void { 45 | c.gtk_grid_insert_column(self.ptr, position); 46 | } 47 | 48 | pub fn remove_row(self: Self, position: c_int) void { 49 | c.gtk_grid_remove_row(self.ptr, position); 50 | } 51 | 52 | pub fn remove_column(self: Self, position: c_int) void { 53 | c.gtk_grid_remove_column(self.ptr, position); 54 | } 55 | 56 | pub fn insert_next_to(self: Self, sibling: Widget, side: PositionType) void { 57 | c.gtk_grid_insert_next_to(self.ptr, sibling.ptr, @enumToInt(side)); 58 | } 59 | 60 | pub fn set_row_homogeneous(self: Self, hom: bool) void { 61 | c.gtk_grid_set_row_homogeneous(self.ptr, if (hom) 1 else 0); 62 | } 63 | 64 | pub fn get_row_homogeneous(self: Self) bool { 65 | return (c.gtk_grid_get_row_homogeneous(self.ptr) == 1); 66 | } 67 | 68 | pub fn set_row_spacing(self: Self, spacing: c_uint) void { 69 | c.gtk_grid_set_row_spacing(self.ptr, spacing); 70 | } 71 | 72 | pub fn get_row_spacing(self: Self) c_uint { 73 | return c.gtk_grid_get_row_spacing(self.ptr); 74 | } 75 | 76 | pub fn set_column_homogeneous(self: Self, hom: bool) void { 77 | c.gtk_grid_set_column_homogeneous(self.ptr, if (hom) 1 else 0); 78 | } 79 | 80 | pub fn get_column_homogeneous(self: Self) bool { 81 | return (c.gtk_grid_get_column_homogeneous(self.ptr) == 1); 82 | } 83 | 84 | pub fn set_column_spacing(self: Self, spacing: c_uint) void { 85 | c.gtk_grid_set_column_spacing(self.ptr, spacing); 86 | } 87 | 88 | pub fn get_column_spacing(self: Self) c_uint { 89 | return c.gtk_grid_get_column_spacing(self.ptr); 90 | } 91 | 92 | pub fn get_baseline_row(self: Self) c_int { 93 | return c.gtk_grid_get_baseline_row(self.ptr); 94 | } 95 | 96 | pub fn set_baseline_row(self: Self, row: c_int) void { 97 | c.gtk_grid_set_baseline_row(self.ptr, row); 98 | } 99 | 100 | pub fn get_row_baseline_position(self: Self, row: c_int) BaselinePosition { 101 | return @intToEnum(BaselinePosition, c.gtk_grid_get_baseline_position(self.ptr, row)); 102 | } 103 | 104 | pub fn set_row_baseline_position(self: Self, row: c_int, pos: BaselinePosition) void { 105 | c.gtk_grid_set_row_baseline_position(self.ptr, row, @enumToInt(pos)); 106 | } 107 | 108 | pub fn as_buildable(self: Self) Buildable { 109 | return Buildable{ 110 | .ptr = @ptrCast(*c.GtkBuildable, self.ptr), 111 | }; 112 | } 113 | 114 | pub fn as_container(self: Self) Container { 115 | return Container{ 116 | .ptr = @ptrCast(*c.GtkContainer, self.ptr), 117 | }; 118 | } 119 | 120 | pub fn as_orientable(self: Self) Orientable { 121 | return Orientable{ 122 | .ptr = @ptrCast(*c.GtkOrientable, self.ptr), 123 | }; 124 | } 125 | 126 | pub fn as_widget(self: Self) Widget { 127 | return Widget{ 128 | .ptr = @ptrCast(*c.GtkWidget, self.ptr), 129 | }; 130 | } 131 | 132 | pub fn is_instance(gtype: u64) bool { 133 | return (gtype == c.gtk_grid_get_type()); 134 | } 135 | 136 | pub fn to_grid(self: Self) ?Grid { 137 | return if (self.isa(Grid)) Grid{ 138 | .ptr = @ptrCast(*c.GtkGrid, self.ptr), 139 | } else null; 140 | } 141 | }; 142 | -------------------------------------------------------------------------------- /src/gtk.zig: -------------------------------------------------------------------------------- 1 | /// The Gtk+ Adjustment class 2 | pub usingnamespace @import("actionable.zig"); 3 | pub usingnamespace @import("actionbar.zig"); 4 | pub usingnamespace @import("adjustment.zig"); 5 | pub usingnamespace @import("appchooser.zig"); 6 | pub usingnamespace @import("bin.zig"); 7 | pub usingnamespace @import("box.zig"); 8 | pub usingnamespace @import("buildable.zig"); 9 | pub usingnamespace @import("builder.zig"); 10 | pub usingnamespace @import("button.zig"); 11 | pub usingnamespace @import("buttonbox.zig"); 12 | pub usingnamespace @import("colorchooser.zig"); 13 | pub usingnamespace @import("combobox.zig"); 14 | pub usingnamespace @import("container.zig"); 15 | pub usingnamespace @import("common.zig"); 16 | pub usingnamespace @import("dialog.zig"); 17 | pub usingnamespace @import("entry.zig"); 18 | pub usingnamespace @import("enums.zig"); 19 | pub usingnamespace @import("expander.zig"); 20 | pub usingnamespace @import("filechooser.zig"); 21 | pub usingnamespace @import("filefilter.zig"); 22 | pub usingnamespace @import("fixed.zig"); 23 | pub usingnamespace @import("flowbox.zig"); 24 | pub usingnamespace @import("fontchooser.zig"); 25 | pub usingnamespace @import("frame.zig"); 26 | pub usingnamespace @import("grid.zig"); 27 | pub usingnamespace @import("headerbar.zig"); 28 | pub usingnamespace @import("image.zig"); 29 | pub usingnamespace @import("invisible.zig"); 30 | pub usingnamespace @import("label.zig"); 31 | pub usingnamespace @import("menu.zig"); 32 | pub usingnamespace @import("notebook.zig"); 33 | pub usingnamespace @import("orientable.zig"); 34 | pub usingnamespace @import("paned.zig"); 35 | pub usingnamespace @import("popover.zig"); 36 | pub usingnamespace @import("range.zig"); 37 | pub usingnamespace @import("revealer.zig"); 38 | pub usingnamespace @import("scrollable.zig"); 39 | pub usingnamespace @import("separator.zig"); 40 | pub usingnamespace @import("spinner.zig"); 41 | pub usingnamespace @import("stack.zig"); 42 | pub usingnamespace @import("switch.zig"); 43 | pub usingnamespace @import("widget.zig"); 44 | pub usingnamespace @import("window.zig"); 45 | -------------------------------------------------------------------------------- /src/headerbar.zig: -------------------------------------------------------------------------------- 1 | const c = @import("cimport.zig"); 2 | const Buildable = @import("buildable.zig").Buildable; 3 | const Container = @import("container.zig").Container; 4 | const Widget = @import("widget.zig").Widget; 5 | 6 | const std = @import("std"); 7 | const fmt = std.fmt; 8 | const mem = std.mem; 9 | 10 | pub const HeaderBar = struct { 11 | ptr: c.GtkHeaderBar, 12 | 13 | const Self = @This(); 14 | 15 | pub fn new() Self { 16 | return Self{ 17 | .ptr = @ptrCast(*c.GtkHeaderBar, c.gtk_header_bar_new()), 18 | }; 19 | } 20 | 21 | pub fn set_title(self: Self, title: [:0]const u8) void { 22 | c.gtk_header_bar_set_title(self.ptr, title.ptr); 23 | } 24 | 25 | pub fn get_title(self: Self, allocator: mem.Allocator) ?[:0]const u8 { 26 | const val = c.gtk_header_bar_get_title(self.ptr); 27 | const len = mem.len(val); 28 | return fmt.allocPrintZ(allocator, "{s}", .{val[0..len]}) catch return null; 29 | } 30 | 31 | pub fn set_subtitle(self: Self, sub: [:0]const u8) void { 32 | c.gtk_header_bar_set_subtitle(self.ptr, sub.ptr); 33 | } 34 | 35 | pub fn get_subtitle(self: Self, allocator: mem.Allocator) ?[:0]const u8 { 36 | if (c.gtk_header_bar_get_subtitle(self.ptr)) |val| { 37 | const len = mem.len(val); 38 | return fmt.allocPrintZ(allocator, "{s}", .{val[0..len]}) catch return null; 39 | } else return null; 40 | } 41 | 42 | pub fn set_has_subtitle(self: Self, set: bool) void { 43 | c.gtk_header_bar_set_has_subtitle(self.ptr, if (set) 1 else 0); 44 | } 45 | 46 | pub fn get_has_subtitle(self: Self) bool { 47 | return (c.gtk_header_bar_get_has_subtitle(self.ptr) == 1); 48 | } 49 | 50 | pub fn set_custom_title(self: Self, title: ?Widget) void { 51 | c.gtk_header_bar_set_custom_title(self.ptr, if (title) |t| t.ptr else null); 52 | } 53 | 54 | pub fn get_custom_title(self: Self) ?Widget { 55 | return if (c.gtk_header_bar_get_custom_title(self.ptr)) |t| Widget{ 56 | .ptr = t, 57 | } else null; 58 | } 59 | 60 | pub fn pack_start(self: Self, child: Widget) void { 61 | c.gtk_header_bar_pack_start(self.ptr, child.ptr); 62 | } 63 | 64 | pub fn pack_end(self: Self, child: Widget) void { 65 | c.gtk_header_bar_pack_end(self.ptr, child.ptr); 66 | } 67 | 68 | pub fn set_show_close_button(self: Self, show: bool) void { 69 | c.gtk_header_bar_set_show_close_button(self.ptr, if (show) 1 else 0); 70 | } 71 | 72 | pub fn get_show_close_button(self: Self) bool { 73 | return (c.gtk_header_bar_get_show_close_button(self.ptr) == 1); 74 | } 75 | 76 | pub fn set_decoration_layout(self: Self, layout: [:0]const u8) void { 77 | c.gtk_header_bar_set_decoration_layout(self.ptr, layout.ptr); 78 | } 79 | 80 | pub fn get_decoration_layout(self: Self, allocator: mem.Allocator) ?[:0]const u8 { 81 | const val = c.gtk_header_bar_get_decoration_layout(self.ptr); 82 | const len = mem.len(val); 83 | return fmt.allocPrintZ(allocator, "{s}", .{val[0..len]}) catch return null; 84 | } 85 | 86 | pub fn as_buildable(self: Self) Buildable { 87 | return Buildable{ 88 | .ptr = @ptrCast(*c.GtkBuildable, self.ptr), 89 | }; 90 | } 91 | 92 | pub fn as_container(self: Self) Container { 93 | return Container{ 94 | .ptr = @ptrCast(*c.GtkContainer, self.ptr), 95 | }; 96 | } 97 | 98 | pub fn as_widget(self: Self) Widget { 99 | return Widget{ 100 | .ptr = @ptrCast(*c.GtkWidget, self.ptr), 101 | }; 102 | } 103 | 104 | pub fn is_instance(gtype: u64) bool { 105 | return (gtype == c.gtk_header_bar_get_type()); 106 | } 107 | }; 108 | -------------------------------------------------------------------------------- /src/image.zig: -------------------------------------------------------------------------------- 1 | const c = @import("cimport.zig"); 2 | const Widget = @import("widget.zig").Widget; 3 | 4 | const std = @import("std"); 5 | 6 | /// The GtkImage widget displays an image. Various kinds of object can be 7 | /// displayed as an image; most typically, you would load a GdkPixbuf ("pixel 8 | /// buffer") from a file, and then display that. There’s a convenience function 9 | /// to do this, gtk_image_new_from_file(), used as follows: 10 | /// ``` 11 | /// const image = Image.new_from_file ("myfile.png"); 12 | /// ``` 13 | /// If the file isn’t loaded successfully, the image will contain a “broken image” 14 | /// icon similar to that used in many web browsers. If you want to handle errors 15 | /// in loading the file yourself, for example by displaying an error message, 16 | /// then load the image with gdk_pixbuf_new_from_file(), then create the GtkImage 17 | /// with gtk_image_new_from_pixbuf(). 18 | /// 19 | /// The image file may contain an animation, if so the GtkImage will display an 20 | /// animation (GdkPixbufAnimation) instead of a static image. 21 | /// 22 | /// GtkImage is a subclass of GtkMisc, which implies that you can align it (center, 23 | /// left, right) and add padding to it, using GtkMisc methods. 24 | /// 25 | /// GtkImage is a “no window” widget (has no GdkWindow of its own), so by default 26 | /// does not receive events. If you want to receive events on the image, such as 27 | /// button clicks, place the image inside a GtkEventBox, then connect to the event 28 | /// signals on the event box. 29 | /// 30 | /// When handling events on the event box, keep in mind that coordinates in the 31 | /// image may be different from event box coordinates due to the alignment and 32 | /// padding settings on the image (see GtkMisc). The simplest way to solve this 33 | /// is to set the alignment to 0.0 (left/top), and set the padding to zero. Then 34 | /// the origin of the image will be the same as the origin of the event box. 35 | /// 36 | /// Sometimes an application will want to avoid depending on external data files, 37 | /// such as image files. GTK+ comes with a program to avoid this, called 38 | /// “gdk-pixbuf-csource”. This library allows you to convert an image into a C 39 | /// variable declaration, which can then be loaded into a GdkPixbuf using 40 | /// gdk_pixbuf_new_from_inline(). 41 | /// ### CSS 42 | /// GtkImage has a single CSS node with the name image. The style classes may 43 | /// appear on image CSS nodes: .icon-dropshadow, .lowres-icon. 44 | pub const Image = struct { 45 | ptr: *c.GtkImage, 46 | 47 | const Self = @This(); 48 | 49 | pub const IconDesc = struct { 50 | name: [:0]const u8, 51 | size: c_uint, 52 | }; 53 | 54 | pub const GIconDesc = struct { 55 | gicon: *c.gicon, 56 | size: IconSize, 57 | }; 58 | 59 | /// Built-in stock icon sizes. 60 | pub const IconSize = enum(c_uint) { 61 | /// Invalid size. 62 | invalid = c.GTK_ICON_SIZE_INVALID, 63 | /// Size appropriate for menus (16px). 64 | menu = c.GTK_ICON_SIZE_MENU, 65 | /// Size appropriate for small toolbars (16px). 66 | small_toolbar = c.GTK_ICON_SIZE_SMALL_TOOLBAR, 67 | /// Size appropriate for large toolbars (24px). 68 | large_toolbar = c.GTK_ICON_SIZE_LARGE_TOOLBAR, 69 | /// Size appropriate for buttons (16px). 70 | button = c.GTK_ICON_SIZE_BUTTON, 71 | /// Size appropriate for drag and drop (32px). 72 | dnd = c.GTK_ICON_SIZE_DND, 73 | /// Size appropriate for dialogs (48px). 74 | dialog = c.GTK_ICON_SIZE_DIALOG, 75 | }; 76 | 77 | /// Describes the image data representation used by a GtkImage. If you want 78 | /// to get the image from the widget, you can only get the currently-stored 79 | /// representation. e.g. if the gtk_image_get_storage_type() returns 80 | /// GTK_IMAGE_PIXBUF, then you can call gtk_image_get_pixbuf() but not 81 | /// gtk_image_get_stock(). For empty images, you can request any storage 82 | /// type (call any of the "get" functions), but they will all return NULL 83 | /// values. 84 | pub const Type = enum(c_uint) { 85 | /// there is no image displayed by the widget 86 | empty = c.GTK_IMAGE_TYPE_EMPTY, 87 | /// the widget contains a GdkPixbuf 88 | pixbuf = c.GTK_IMAGE_TYPE_PIXBUF, 89 | /// the widget contains a stock item name 90 | stock = c.GTK_IMAGE_TYPE_STOCK, 91 | /// the widget contains a GtkIconSet 92 | icon_set = c.GTK_IMAGE_TYPE_ICON_SET, 93 | /// the widget contains a GdkPixbufAnimation 94 | animation = c.GTK_IMAGE_TYPE_ANIMATION, 95 | /// the widget contains a named icon. This image type was added in GTK+ 96 | /// 2.6 97 | icon_name = c.GTK_IMAGE_TYPE_ICON_NAME, 98 | /// the widget contains a GIcon. This image type was added in GTK+ 2.14 99 | gicon = c.GTK_IMAGE_TYPE_GICON, 100 | /// the widget contains a cairo_surface_t. This image type was added in 101 | /// GTK+ 3.10 102 | surface = c.GTK_ICON_TYPE_SURFACE, 103 | }; 104 | 105 | /// Gets the GdkPixbuf being displayed by the GtkImage. The storage type of 106 | /// the image must be GTK_IMAGE_EMPTY or GTK_IMAGE_PIXBUF (see 107 | /// gtk_image_get_storage_type()). The caller of this function does not own 108 | /// a reference to the returned pixbuf. 109 | pub fn get_pixbuf(self: Self) ?*c.GdkPixbuf { 110 | return if (c.gtk_image_get_pixbuf(self.ptr)) |p| p else null; 111 | } 112 | 113 | /// Gets the GdkPixbufAnimation being displayed by the GtkImage. The storage 114 | /// type of the image must be GTK_IMAGE_EMPTY or GTK_IMAGE_ANIMATION (see 115 | /// gtk_image_get_storage_type()). The caller of this function does not own 116 | /// a reference to the returned animation. 117 | pub fn get_animation(self: Self) ?*c.GdkPixbufAnimation { 118 | return if (c.gtk_image_get_animation(self.ptr)) |a| a else null; 119 | } 120 | 121 | /// Gets the icon name and size being displayed by the GtkImage. The storage 122 | /// type of the image must be GTK_IMAGE_EMPTY or GTK_IMAGE_ICON_NAME (see 123 | /// gtk_image_get_storage_type()). The returned string is owned by the 124 | /// GtkImage and should not be freed. 125 | pub fn get_icon_name(self: Self) IconDesc { 126 | var name: [:0]const u8 = undefined; 127 | var size: c_uint = undefined; 128 | c.gtk_image_get_icon_name(self.ptr & name.ptr, &size); 129 | return IconDesc{ 130 | .name = name, 131 | .size = size, 132 | }; 133 | } 134 | 135 | /// Gets the GIcon and size being displayed by the GtkImage. The storage 136 | /// type of the image must be GTK_IMAGE_EMPTY or GTK_IMAGE_GICON (see 137 | /// gtk_image_get_storage_type()). The caller of this function does not own 138 | /// a reference to the returned GIcon. 139 | pub fn get_gicon(self: Self) GIconDesc { 140 | var gicon: *c.gicon = undefined; 141 | var size: IconSize = undefined; 142 | c.gtk_image_get_gicon(self.ptr, gicon, &size); 143 | return GIconDesc{ 144 | .gicon = gicon, 145 | .size = @enumToInt(size), 146 | }; 147 | } 148 | 149 | /// Gets the type of representation being used by the GtkImage to store image 150 | /// data. If the GtkImage has no image data, the return value will be 151 | /// GTK_IMAGE_EMPTY. 152 | pub fn get_storage_type(self: Self) Type { 153 | return @intToEnum(Type, c.gtk_image_get_storage_type(self.ptr)); 154 | } 155 | 156 | /// Creates a new GtkImage displaying the file filename . If the file isn’t 157 | /// found or can’t be loaded, the resulting GtkImage will display a “broken 158 | /// image” icon. This function never returns NULL, it always returns a valid 159 | /// GtkImage widget. 160 | /// 161 | /// If the file contains an animation, the image will contain an animation. 162 | /// 163 | /// If you need to detect failures to load the file, use 164 | /// gdk_pixbuf_new_from_file() to load the file yourself, then create the 165 | /// GtkImage from the pixbuf. (Or for animations, use 166 | /// gdk_pixbuf_animation_new_from_file()). 167 | /// 168 | /// The storage type (gtk_image_get_storage_type()) of the returned image is 169 | /// not defined, it will be whatever is appropriate for displaying the file. 170 | pub fn new_from_file(file: [:0]const u8) Self { 171 | return Self{ 172 | .ptr = @ptrCast(*c.GtkImage, c.gtk_image_new_from_file(file.ptr)), 173 | }; 174 | } 175 | 176 | /// Creates a new GtkImage displaying pixbuf . The GtkImage does not assume 177 | /// a reference to the pixbuf; you still need to unref it if you own references. 178 | /// GtkImage will add its own reference rather than adopting yours. 179 | /// 180 | /// Note that this function just creates an GtkImage from the pixbuf. The 181 | /// GtkImage created will not react to state changes. Should you want that, 182 | /// you should use gtk_image_new_from_icon_name(). 183 | pub fn new_from_pixbuf(pixbuf: ?*c.GdkPixbuf) Self { 184 | return Self{ 185 | .ptr = @ptrCast(*c.GtkImage, c.gtk_image_new_from_pixbuf(if (pixbuf) |p| p else null)), 186 | }; 187 | } 188 | 189 | pub fn as_widget(self: Self) Widget { 190 | return Widget{ 191 | .ptr = @ptrCast(*c.GtkWidget, self.ptr), 192 | }; 193 | } 194 | 195 | pub fn is_instance(gtype: u64) bool { 196 | return (gtype == c.gtk_image_get_type()); 197 | } 198 | }; 199 | -------------------------------------------------------------------------------- /src/invisible.zig: -------------------------------------------------------------------------------- 1 | const c = @import("cimport.zig"); 2 | const Buildable = @import("buildable.zig").Buildable; 3 | const Widget = @import("widget.zig").Widget; 4 | 5 | const std = @import("std"); 6 | 7 | pub const Invisible = struct { 8 | ptr: *c.GtkInvisible, 9 | 10 | const Self = @This(); 11 | 12 | pub fn new() Self { 13 | return Self{ 14 | .ptr = @ptrCast(*c.GtkInvisible, c.gtk_invisible_new()), 15 | }; 16 | } 17 | 18 | pub fn new_for_screen(screen: *c.GdkScreen) Self { 19 | return Self{ 20 | .ptr = @ptrCast(*c.GtkInvisible, c.gtk_invisible_new_for_screen(screen)), 21 | }; 22 | } 23 | 24 | pub fn set_screen(self: Self, screen: *c.GdkScreen) void { 25 | c.gtk_invisible_set_screen(self.ptr, screen); 26 | } 27 | 28 | pub fn get_screen(self: Self) *c.GdkScreen { 29 | return c.gtk_invisible_get_screen(self.ptr); 30 | } 31 | 32 | pub fn as_buildable(self: Self) Buildable { 33 | return Buildable{ .ptr = @ptrCast(*c.GtkBuildable, self.ptr) }; 34 | } 35 | 36 | pub fn as_widget(self: Self) Widget { 37 | return Widget{ .ptr = @ptrCast(*c.GtkWidget, self.ptr) }; 38 | } 39 | 40 | pub fn is_instance(gtype: u64) bool { 41 | return (gtype == c.gtk_invisible_get_type()); 42 | } 43 | }; 44 | -------------------------------------------------------------------------------- /src/layout.zig: -------------------------------------------------------------------------------- 1 | const c = @import("cimport.zig"); 2 | const Adjustment = @import("adjustment.zig").Adjustment; 3 | const Buildable = @import("buildable.zig").Buildable; 4 | const Container = @import("container.zig").Container; 5 | const Scrollable = @import("scrollable.zig").Scrollable; 6 | const Widget = @import("widget.zig").Widget; 7 | const Window = @import("window.zig").Window; 8 | 9 | /// GtkLayout is similar to GtkDrawingArea in that it’s a “blank slate” and 10 | /// doesn’t do anything except paint a blank background by default. It’s 11 | /// different in that it supports scrolling natively due to implementing 12 | /// GtkScrollable, and can contain child widgets since it’s a GtkContainer. 13 | /// 14 | /// If you just want to draw, a GtkDrawingArea is a better choice since it has 15 | /// lower overhead. If you just need to position child widgets at specific 16 | /// points, then GtkFixed provides that functionality on its own. 17 | /// 18 | /// When handling expose events on a GtkLayout, you must draw to the GdkWindow 19 | /// returned by gtk_layout_get_bin_window(), rather than to the one returned by 20 | /// gtk_widget_get_window() as you would for a GtkDrawingArea. 21 | pub const Layout = struct { 22 | ptr: *c.GtkLayout, 23 | 24 | const Self = @This(); 25 | 26 | pub const Size = struct { 27 | x: c_uint, 28 | y: c_uint, 29 | }; 30 | 31 | /// Creates a new GtkLayout. Unless you have a specific adjustment you’d 32 | /// like the layout to use for scrolling, pass NULL for hadjustment and 33 | /// vadjustment. 34 | pub fn new(horizontal: Adjustment, vertical: Adjustment) Self { 35 | return Self{ 36 | .ptr = @ptrCast(*c.GtkLayout, c.gtk_layout_new(horizontal, vertical)), 37 | }; 38 | } 39 | 40 | /// Adds child_widget to layout , at position (x ,y ). layout becomes the 41 | /// new parent container of child_widget. 42 | pub fn put(self: Self, child: Widget, x: c_int, y: c_int) void { 43 | c.gtk_layout_put(self.ptr, child.ptr, x, y); 44 | } 45 | 46 | /// Moves a current child of layout to a new position. 47 | pub fn move(self: Self, child: Widget, x: c_int, y: c_int) void { 48 | c.gtk_layout_move(self.ptr, child.ptr, x, y); 49 | } 50 | 51 | /// Sets the size of the scrollable area of the layout. 52 | pub fn set_size(self: Self, x: c_uint, y: c_uint) void { 53 | c.gtk_layout_set_size(self.ptr, x, y); 54 | } 55 | 56 | /// Gets the size that has been set on the layout, and that determines the 57 | /// total extents of the layout’s scrollbar area. See gtk_layout_set_size(). 58 | pub fn get_size(self: Self) Size { 59 | var x: c_uint = undefined; 60 | var y: c_uint = undefined; 61 | c.gtk_layout_get_size(self.ptr, &x, &y); 62 | return Size{ .x = x, .y = y }; 63 | } 64 | 65 | /// Retrieve the bin window of the layout used for drawing operations. 66 | pub fn get_bin_window(self: Self) Window { 67 | return Window{ 68 | .ptr = @ptrCast(*c.GtkWindow, c.gtk_layout_get_bin_window(self.ptr)), 69 | }; 70 | } 71 | 72 | pub fn as_buildable(self: Self) Buildable { 73 | return Buildable{ 74 | .ptr = @ptrCast(*c.GtkBuildable, self.ptr), 75 | }; 76 | } 77 | 78 | pub fn as_container(self: Self) Container { 79 | return Container{ 80 | .ptr = @ptrCast(*c.GtkContainer, self.ptr), 81 | }; 82 | } 83 | 84 | pub fn as_scrollable(self: Self) Scrollable { 85 | return Scrollable{ 86 | .ptr = @ptrCast(*c.GtkScrollable, self.ptr), 87 | }; 88 | } 89 | 90 | pub fn as_widget(self: Self) Widget { 91 | return Widget{ 92 | .ptr = @ptrCast(*c.GtkWidget, self.ptr), 93 | }; 94 | } 95 | 96 | pub fn is_instance(gtype: u64) bool { 97 | return (gtype == c.gtk_layout_get_type()); 98 | } 99 | }; 100 | -------------------------------------------------------------------------------- /src/menu.zig: -------------------------------------------------------------------------------- 1 | const c = @import("cimport.zig"); 2 | 3 | const Actionable = @import("actionable.zig").Actionable; 4 | const Container = @import("container.zig").Container; 5 | const Widget = @import("widget.zig").Widget; 6 | 7 | const std = @import("std"); 8 | const fmt = std.fmt; 9 | const mem = std.mem; 10 | 11 | pub const Menu = struct { 12 | ptr: *c.GtkMenu, 13 | 14 | const Self = @This(); 15 | 16 | pub fn new() Self { 17 | return Self{ 18 | .ptr = @ptrCast(*c.GtkMenu, c.gtk_menu_new()), 19 | }; 20 | } 21 | 22 | pub fn get_accel_group(self: Self) *c.GtkAccelGroup { 23 | return c.gtk_menu_get_accel_group(self.ptr); 24 | } 25 | 26 | pub fn as_widget(self: Self) Widget { 27 | return Widget{ 28 | .ptr = @ptrCast(*c.GtkWidget, self.ptr), 29 | }; 30 | } 31 | 32 | pub fn is_instance(gtype: u64) bool { 33 | return (gtype == c.gtk_menu_get_type()); 34 | } 35 | }; 36 | 37 | pub const MenuItem = struct { 38 | ptr: *c.GtkMenuItem, 39 | 40 | const Self = @This(); 41 | 42 | pub fn new() Self { 43 | return Self{ 44 | .ptr = @ptrCast(*c.GtkMenuItem, c.gtk_menu_tem_new()), 45 | }; 46 | } 47 | 48 | pub fn new_with_label(text: [:0]const u8) Self { 49 | return Self{ 50 | .ptr = @ptrCast(*c.GtkMenuItem, c.gtk_menu_item_new_with_label(text.ptr)), 51 | }; 52 | } 53 | 54 | pub fn new_with_mnemonic(text: [:0]const u8) Self { 55 | return Self{ 56 | .ptr = @ptrCast(*c.GtkMenuItem, c.gtk_menu_item_new_with_mnemonic(text.ptr)), 57 | }; 58 | } 59 | 60 | pub fn get_label(self: Self, allocator: mem.Allocator) ?[:0]const u8 { 61 | if (c.gtk_menu_item_get_label(self.ptr)) |v| { 62 | const len = mem.len(v); 63 | return fmt.allocPrintZ(allocator, "{s}", .{v[0..len]}) catch { 64 | return null; 65 | }; 66 | } else return null; 67 | } 68 | 69 | pub fn set_label(self: Self, text: [:0]const u8) void { 70 | c.gtk_menu_item_set_label(self.ptr, text.ptr); 71 | } 72 | 73 | pub fn get_use_underline(self: Self) bool { 74 | return (c.gtk_menu_item_get_use_underline(self.ptr) == 1); 75 | } 76 | 77 | pub fn set_use_underline(self: Self, use: bool) void { 78 | c.gtk_menu_item_set_use_underline(self.ptr, if (use) 1 else 0); 79 | } 80 | 81 | pub fn set_submenu(self: Self, widget: Widget) void { 82 | c.gtk_menu_item_set_submenu(self.ptr, widget.ptr); 83 | } 84 | 85 | pub fn get_submenu(self: Self) ?Widget { 86 | return if (c.gtk_menu_item_get_submenu(self.ptr)) |s| Widget{ .ptr = s } else null; 87 | } 88 | 89 | pub fn set_accel_path(self: Self, path: ?[:0]const u8) void { 90 | c.gtk_menu_item_set_accel_path(self.ptr, if (path) |p| p.ptr else null); 91 | } 92 | 93 | pub fn get_accel_path(self: Self, allocator: mem.Allocator) ?[:0]const u8 { 94 | if (c.gtk_menu_item_get_accel_path(self.ptr)) |v| { 95 | const len = mem.len(v); 96 | return fmt.allocPrintZ(allocator, "{s}", .{v[0..len]}) catch { 97 | return null; 98 | }; 99 | } else return null; 100 | } 101 | 102 | pub fn get_reserve_indicator(self: Self) bool { 103 | return (c.gtk_menu_item_get_reserve_indicator(self.ptr) == 1); 104 | } 105 | 106 | pub fn connect_activate(self: Self, callback: c.GCallback, data: ?c.gpointer) void { 107 | self.as_widget().connect("activate", callback, if (data) |d| d else null); 108 | } 109 | 110 | pub fn as_actionable(self: Self) Actionable { 111 | return Actionable{ 112 | .ptr = @ptrCast(*c.GtkActionable, self.ptr), 113 | }; 114 | } 115 | 116 | pub fn as_container(self: Self) Container { 117 | return Container{ 118 | .ptr = @ptrCast(*c.GtkContainer, self.ptr), 119 | }; 120 | } 121 | 122 | pub fn as_widget(self: Self) Widget { 123 | return Widget{ 124 | .ptr = @ptrCast(*c.GtkWidget, self.ptr), 125 | }; 126 | } 127 | 128 | pub fn is_instance(gtype: u64) bool { 129 | return (gtype == c.gtk_menu_item_get_type()); 130 | } 131 | }; 132 | -------------------------------------------------------------------------------- /src/notebook.zig: -------------------------------------------------------------------------------- 1 | const c = @import("cimport.zig"); 2 | const Container = @import("container.zig").Container; 3 | const enums = @import("enums.zig"); 4 | const PackType = enums.PackType; 5 | const PositionType = enums.PositionType; 6 | const Widget = @import("widget.zig").Widget; 7 | 8 | const std = @cImport("std"); 9 | const fmt = std.fmt; 10 | const mem = std.mem; 11 | 12 | pub const Notebook = struct { 13 | ptr: *c.GtkNotebook, 14 | 15 | pub fn new() Notebook { 16 | return Notebook{ 17 | .ptr = c.gtk_notebook_new(), 18 | }; 19 | } 20 | 21 | pub fn append_page(self: Notebook, child: Widget, label: Widget) void { 22 | _ = c.gtk_notebook_append_page(self.ptr, child.ptr, label.ptr); 23 | } 24 | 25 | pub fn append_page_menu(self: Notebook, child: Widget, tab_label: Widget, menu_label: Widget) void { 26 | _ = c.gtk_notebook_append_page_menu(self.ptr, child.ptr, tab_label.ptr, menu_label.ptr); 27 | } 28 | 29 | pub fn prepend_page(self: Notebook, child: Widget, label: Widget) void { 30 | _ = c.gtk_notebook_prepend_page(self.ptr, child.ptr, label.ptr); 31 | } 32 | 33 | pub fn prepend_page_menu(self: Notebook, child: Widget, tab_label: Widget, menu_label: Widget) void { 34 | _ = c.gtk_notebook_prepend_page_menu(self.ptr, child.ptr, tab_label.ptr, menu_label.ptr); 35 | } 36 | 37 | pub fn insert_page(self: Notebook, child: Widget, label: Widget, pos: c_int) void { 38 | _ = c.gtk_notebook_insert_page(self.ptr, child.ptr, label.ptr, pos); 39 | } 40 | 41 | pub fn inset_page_menu(self: Notebook, child: Widget, tab_label: Widget, menu_label: Widget) void { 42 | _ = c.gtk_notebook_insert_page_menu(self.ptr, child.ptr, tab_label.ptr, menu_label.ptr); 43 | } 44 | 45 | pub fn remove_page(self: Notebook, pnum: c_int) void { 46 | _ = c.gtk_notebook_remove_page(self.ptr, pnum); 47 | } 48 | 49 | pub fn detach_tab(self: Notebook, child: Widget) void { 50 | _ = c.gtk_notebook_detach_tab(self.ptr, child.ptr); 51 | } 52 | 53 | pub fn page_num(self: Notebook, child: Widget) ?c_int { 54 | const val = c.gtk_notebook_page_num(self.ptr, child.ptr); 55 | return if (val == -1) null else val; 56 | } 57 | 58 | pub fn next_page(self: Notebook) void { 59 | c.gtk_notebook_next_page(self.ptr); 60 | } 61 | 62 | pub fn prev_page(self: Notebook) void { 63 | c.gtk_notebook_prev_page(self.ptr); 64 | } 65 | 66 | pub fn reorder_child(self: Notebook, child: Widget, pos: c_int) void { 67 | c.gtk_notebook_reorder_child(self.ptr, child.ptr, pos); 68 | } 69 | 70 | pub fn set_tab_pos(self: Notebook, pos: PositionType) void { 71 | c.gtk_notebook_set_tab_pos(self.ptr, @enumToInt(pos)); 72 | } 73 | 74 | pub fn set_show_tabs(self: Notebook, show: bool) void { 75 | c.gtk_notebook_set_show_tabs(self.ptr, if (show) 1 else 0); 76 | } 77 | 78 | pub fn set_show_border(self: Notebook, show: bool) void { 79 | c.gtk_notebook_set_show_border(self.ptr, if (show) 1 else 0); 80 | } 81 | 82 | pub fn set_scrollable(self: Notebook, scrollable: bool) void { 83 | c.gtk_notebook_set_scrollable(self.ptr, if (scrollable) 1 else 0); 84 | } 85 | 86 | pub fn popup_enable(self: Notebook) void { 87 | c.gtk_notebook_popup_enable(self.ptr); 88 | } 89 | 90 | pub fn popup_disable(self: Notebook) void { 91 | c.gtk_notebook_popup_disable(self.ptr); 92 | } 93 | 94 | pub fn get_current_page(self: Notebook) c_int { 95 | return c.gtk_notebook_get_current_page(self.ptr); 96 | } 97 | 98 | pub fn get_menu_label(self: Notebook, child: Widget) ?Widget { 99 | return if (c.gtk_notebook_get_menu_label(self.ptr, child.ptr)) |p| Widget{ 100 | .ptr = p, 101 | } else null; 102 | } 103 | 104 | pub fn get_nth_page(self: Notebook, num: c_int) ?Widget { 105 | return if (c.gtk_notebook_get_nth_page(self.ptr, num)) |p| Widget{ 106 | .ptr = p, 107 | } else null; 108 | } 109 | 110 | pub fn get_n_pages(self: Notebook) c_int { 111 | return c.gtk_notebook_get_n_pages(self.ptr); 112 | } 113 | 114 | pub fn get_tab_label(self: Notebook, child: Widget) ?Widget { 115 | return if (c.gtk_notebook_get_tab_label(self.ptr, child.ptr)) |p| Widget{ 116 | .ptr = p, 117 | } else null; 118 | } 119 | 120 | pub fn set_menu_label(self: Notebook, child: Widget, label: ?Widget) void { 121 | c.gtk_notebook_set_menu_label(self.ptr, child.ptr, if (label) |l| l.ptr else null); 122 | } 123 | 124 | pub fn set_menu_label_text(self: Notebook, child: Widget, text: [:0]const u8) void { 125 | c.gtk_notebook_set_menu_label_text(self.ptr, child.ptr, text.ptr); 126 | } 127 | 128 | pub fn set_tab_label(self: Notebook, child: Widget, label: ?Widget) void { 129 | c.gtk_notebook_set_tab_label(self.ptr, child.ptr, if (label) |l| l.ptr else null); 130 | } 131 | 132 | pub fn set_tab_label_text(self: Notebook, child: Widget, text: [:0]const u8) void { 133 | c.gtk_notebook_set_tab_label_text(self.ptr, child.ptr, text.ptr); 134 | } 135 | 136 | pub fn set_tab_reorderable(self: Notebook, child: Widget, reorderable: bool) void { 137 | c.gtk_notebook_set_tab_reorderable(self.ptr, child.ptr, if (reorderable) 1 else 0); 138 | } 139 | 140 | pub fn set_tab_detachable(self: Notebook, child: Widget, detachable: bool) void { 141 | c.gtk_notebook_set_tab_detachable(self.ptr, child.ptr, if (detachable) 1 else 0); 142 | } 143 | 144 | pub fn get_menu_label_text(self: Notebook, allocator: mem.Allocator, child: Widget) ?[:0]const u8 { 145 | if (c.gtk_notebook_get_menu_label_text(self.ptr, child.ptr)) |v| { 146 | const len = mem.len(v); 147 | const text = fmt.allocPrintZ(allocator, "{s}", .{v[0..len]}) catch { 148 | return null; 149 | }; 150 | return text; 151 | } else return null; 152 | } 153 | 154 | pub fn get_scrollable(self: Notebook) bool { 155 | return (c.gtk_notebook_get_scrollable(self.ptr) == 1); 156 | } 157 | 158 | pub fn get_show_border(self: Notebook) bool { 159 | return (c.gtk_notebook_get_show_border(self.ptr) == 1); 160 | } 161 | 162 | pub fn get_show_tabs(self: Notebook) bool { 163 | return (c.gtk_notebook_get_show_tabs(self.ptr) == 1); 164 | } 165 | 166 | pub fn get_tab_label_text(self: Notebook, allocator: mem.Allocator, child: Widget) ?[:0]const u8 { 167 | if (c.gtk_notebook_get_tab_label_text(self.ptr, child.ptr)) |v| { 168 | const len = mem.len(v); 169 | const text = fmt.allocPrintZ(allocator, "{s}", .{v[0..len]}) catch { 170 | return null; 171 | }; 172 | return text; 173 | } else return null; 174 | } 175 | 176 | pub fn get_tab_pos(self: Notebook) PositionType { 177 | return @intToEnum(PositionType, switch (c.gtk_notebook_get_tab_pos(self.ptr)) { 178 | c.GTK_POS_LEFT => .left, 179 | c.GTK_POS_RIGHT => .right, 180 | c.GTK_POS_TOP => .top, 181 | c.GTK_POS_BOTTOM => .bottom, 182 | else => unreachable, 183 | }); 184 | } 185 | 186 | pub fn get_tab_reorderable(self: Notebook, child: Widget) bool { 187 | return (c.gtk_notebook_get_tab_reorderable(self.ptr, child.ptr) == 1); 188 | } 189 | 190 | pub fn get_tab_detachable(self: Notebook, child: Widget) bool { 191 | return (c.gtk_notebook_get_tab_detachable(self.ptr, child.ptr) == 1); 192 | } 193 | 194 | pub fn set_current_page(self: Notebook, num: c_int) void { 195 | c.gtk_notebook_set_current_page(self.ptr, num); 196 | } 197 | 198 | pub fn set_group_name(self: Notebook, name: [:0]const u8) void { 199 | c.gtk_notebook_set_group_name(self.ptr, name.ptr); 200 | } 201 | 202 | pub fn get_group_name(self: Notebook, allocator: mem.Allocator) ?[:0]const u8 { 203 | if (c.gtk_notebook_get_group_name(self.ptr)) |v| { 204 | const len = mem.len(v); 205 | return fmt.allocPrintZ(allocator, "{s}", .{v[0..len]}) catch { 206 | return null; 207 | }; 208 | } else return null; 209 | } 210 | 211 | pub fn set_action_widget(self: Notebook, widget: Widget, packtype: PackType) void { 212 | c.gtk_notebook_set_action_widget(self.ptr, widget.ptr, @enumToInt(packtype)); 213 | } 214 | 215 | pub fn get_action_widget(self: Notebook, packtype: PackType) ?Widget { 216 | return if (c.gtk_notebook_get_action_widget(self.ptr, @enumToInt(packtype))) |v| Widget{ .ptr = v } else null; 217 | } 218 | 219 | pub fn connect_change_current_page(self: Notebook, callback: c.GCallback, data: ?c.gpointer) void { 220 | self.as_widget().connect("change-current-page", callback, if (data) |d| d else null); 221 | } 222 | 223 | pub fn connect_page_added(self: Notebook, callback: c.GCallback, data: ?c.gpointer) void { 224 | self.as_widget().connect("page-added", callback, if (data) |d| d else null); 225 | } 226 | 227 | pub fn connect_page_removed(self: Notebook, callback: c.GCallback, data: ?c.gpointer) void { 228 | self.as_widget().connect("page-removed", callback, if (data) |d| d else null); 229 | } 230 | 231 | pub fn connect_select_page(self: Notebook, callback: c.GCallback, data: ?c.gpointer) void { 232 | self.as_widget().connect("select-page", callback, if (data) |d| d else null); 233 | } 234 | 235 | pub fn connect_switch_page(self: Notebook, callback: c.GCallback, data: ?c.gpointer) void { 236 | self.as_widget().connect("switch-page", callback, if (data) |d| d else null); 237 | } 238 | 239 | pub fn as_container(self: Notebook) Container { 240 | return Container{ 241 | .ptr = @ptrCast(*c.GtkContainer, self.ptr), 242 | }; 243 | } 244 | 245 | pub fn as_widget(self: Notebook) Widget { 246 | return Widget{ 247 | .ptr = @ptrCast(*c.GtkWidget, self.ptr), 248 | }; 249 | } 250 | 251 | pub fn is_instance(gtype: u64) bool { 252 | return (gtype == c.gtk_notebook_get_type()); 253 | } 254 | }; 255 | -------------------------------------------------------------------------------- /src/orientable.zig: -------------------------------------------------------------------------------- 1 | const c = @import("cimport.zig"); 2 | const enums = @import("enums.zig"); 3 | const Orientation = enums.Orientation; 4 | const Widget = @import("widget.zig").Widget; 5 | 6 | pub const Orientable = struct { 7 | ptr: *c.GtkOrientable, 8 | 9 | pub fn as_widget(self: Orientable) Widget { 10 | return Widget{ 11 | .ptr = @ptrCast(*c.GtkWidget, self.ptr), 12 | }; 13 | } 14 | 15 | pub fn get_orientation(self: Orientable) Orientation { 16 | return @intToEnum(Orientation, c.gtk_orientable_get_orientation(self.ptr)); 17 | } 18 | 19 | pub fn set_orientation(self: Orientable, orientation: Orientation) void { 20 | c.gtk_orientable_set_orientation(self.ptr, @enumToInt(orientation)); 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /src/paned.zig: -------------------------------------------------------------------------------- 1 | const c = @import("cimport.zig"); 2 | const Bin = @import("bin.zig").Bin; 3 | const Container = @import("container.zig").Container; 4 | const Orientable = @import("orientable.zig").Orientable; 5 | const Widget = @import("widget.zig").Widget; 6 | const Window = @import("window.zig").Window; 7 | 8 | pub const Paned = struct { 9 | ptr: *c.GtkPaned, 10 | 11 | const Self = @This(); 12 | 13 | pub fn new() Self { 14 | return Self{ 15 | .ptr = @ptrCast(*c.GtkPaned, c.gtk_paned_new()), 16 | }; 17 | } 18 | 19 | pub fn add1(self: Self, child: Widget) void { 20 | c.gtk_paned_add1(self.ptr, child.ptr); 21 | } 22 | 23 | pub fn add2(self: Self, child: Widget) void { 24 | c.gtk_paned_add2(self.ptr, child.ptr); 25 | } 26 | 27 | pub fn pack1(self: Self, child: Widget, resize: bool, shrink: bool) void { 28 | c.gtk_paned_pack1( 29 | self.ptr, 30 | child.ptr, 31 | if (resize) 1 else 0, 32 | if (shrink) 1 else 0, 33 | ); 34 | } 35 | 36 | pub fn pack2(self: Self, child: Widget, resize: bool, shrink: bool) void { 37 | c.gtk_paned_pack2( 38 | self.ptr, 39 | child.ptr, 40 | if (resize) 1 else 0, 41 | if (shrink) 1 else 0, 42 | ); 43 | } 44 | 45 | pub fn get_child1(self: Self) ?Widget { 46 | return if (c.gtk_paned_get_child1(self.ptr)) |child| Widget{ 47 | .ptr = child, 48 | } else null; 49 | } 50 | 51 | pub fn get_child2(self: Self) ?Widget { 52 | return if (c.gtk_paned_get_child2(self.ptr)) |child| Widget{ 53 | .ptr = child, 54 | } else null; 55 | } 56 | 57 | pub fn set_position(self: Self, pos: c_int) void { 58 | c.gtk_paned_set_position(self.ptr, pos); 59 | } 60 | 61 | pub fn get_position(self: Self) c_int { 62 | return c.gtk_paned_get_position(self.ptr); 63 | } 64 | 65 | pub fn get_handle_window(self: Self) Window { 66 | return Window{ 67 | .ptr = c.gtk_paned_get_handle_window(self.ptr), 68 | }; 69 | } 70 | 71 | pub fn set_wide_handle(self: Self, wide: bool) void { 72 | c.gtk_paned_set_wide_handle(self.ptr, if (wide) 1 else 0); 73 | } 74 | 75 | pub fn get_wide_handle(self: Self) bool { 76 | return (c.gtk_paned_get_wide_handle(self.ptr) == 1); 77 | } 78 | 79 | pub fn as_orientable(self: Self) Orientable { 80 | return Orientable{ 81 | .ptr = @ptrCast(*c.GtkOrientable, self.ptr), 82 | }; 83 | } 84 | 85 | pub fn as_container(self: Self) Container { 86 | return Container{ 87 | .ptr = @ptrCast(*c.GtkContainer, self.ptr), 88 | }; 89 | } 90 | 91 | pub fn as_widget(self: Self) Widget { 92 | return Widget{ 93 | .ptr = @ptrCast(*c.GtkWidget, self.ptr), 94 | }; 95 | } 96 | 97 | pub fn is_instance(gtype: u64) bool { 98 | return (gtype == c.gtk_paned_get_type()); 99 | } 100 | }; 101 | -------------------------------------------------------------------------------- /src/range.zig: -------------------------------------------------------------------------------- 1 | const c = @import("cimport.zig"); 2 | const Adjustment = @import("adjustment.zig").Adjustment; 3 | const enums = @import("enums.zig"); 4 | const Orientation = enums.Orientation; 5 | const PositionType = enums.PositionType; 6 | const SensitivityType = enums.SensitivityType; 7 | const SpinType = enums.SpinType; 8 | const SpinButtonUpdatePolicy = enums.SpinButtonUpdatePolicy; 9 | const Orientable = @import("orientable.zig").Orientable; 10 | const Widget = @import("widget.zig").Widget; 11 | 12 | pub const Range = struct { 13 | ptr: *c.GtkRange, 14 | 15 | const Self = @This(); 16 | 17 | pub fn get_fill_level(self: Self) f64 { 18 | return c.gtk_range_get_fill_level(self.ptr); 19 | } 20 | 21 | pub fn get_restrict_to_fill_level(self: Self) bool { 22 | return (c.gtk_range_get_restrict_to_fill_level(self.ptr) == 1); 23 | } 24 | 25 | pub fn get_show_fill_level(self: Self) bool { 26 | return (c.gtk_range_get_show_fill_level(self.ptr) == 1); 27 | } 28 | 29 | pub fn set_fill_level(self: Self, level: f64) void { 30 | c.gtk_range_set_fill_level(self.ptr, level); 31 | } 32 | 33 | pub fn set_restrict_to_fill_level(self: Self, restrict: bool) void { 34 | c.gtk_range_set_restrict_to_fill_level(self.ptr, if (restrict) 1 else 0); 35 | } 36 | 37 | pub fn set_show_fill_level(self: Self, show: bool) void { 38 | c.gtk_range_set_show_fill_level(self.ptr, if (show) 1 else 0); 39 | } 40 | 41 | pub fn get_adjustment(self: Self) Adjustment { 42 | return Adjustment{ 43 | .ptr = @ptrCast(*c.GtkAdjustment, c.gtk_range_get_adjustment(self.ptr)), 44 | }; 45 | } 46 | 47 | pub fn set_adjustment(self: Self, adjustment: Adjustment) void { 48 | c.gtk_range_set_adjustment(self.ptr, adjustment.ptr); 49 | } 50 | 51 | pub fn get_inverted(self: Self) bool { 52 | return (c.gtk_range_get_inverted(self.ptr) == 1); 53 | } 54 | 55 | pub fn set_inverted(self: Self, inverted: bool) void { 56 | c.gtk_range_set_inverted(self.ptr, if (inverted) 1 else 0); 57 | } 58 | 59 | pub fn get_value(self: Self) f64 { 60 | return c.gtk_range_get_value(self.ptr); 61 | } 62 | 63 | pub fn set_value(self: Self, val: f64) void { 64 | c.gtk_range_set_value(self.ptr, val); 65 | } 66 | 67 | pub fn set_increments(self: Self, step: f64, page: f64) void { 68 | c.gtk_range_set_increments(self.ptr, step, page); 69 | } 70 | 71 | pub fn set_range(self: Self, min: f64, max: f64) void { 72 | c.gtk_range_set_range(self.ptr, min, max); 73 | } 74 | 75 | pub fn get_round_digits(self: Self) c_int { 76 | return c.gtk_range_get_round_digits(self.ptr); 77 | } 78 | 79 | pub fn set_round_digits(self: Self, digits: c_int) void { 80 | c.gtk_range_set_round_digits(self.ptr, digits); 81 | } 82 | 83 | pub fn set_lower_stepper_sensitivity(self: Self, sensitivity: SensitivityType) void { 84 | c.gtk_range_set_lower_stepper_sensitivity(self.ptr, @enumToInt(sensitivity)); 85 | } 86 | 87 | pub fn get_lower_stepper_sensitivity(self: Self) SensitivityType { 88 | return @intToEnum(SensitivityType, c.gtk_range_get_lower_stepper_sensitivity(self.ptr)); 89 | } 90 | 91 | pub fn set_upper_stepper_sensitivity(self: Self, sensitivity: SensitivityType) void { 92 | c.gtk_range_set_upper_stepper_sensitivity(self.ptr, @enumToInt(sensitivity)); 93 | } 94 | 95 | pub fn get_upper_stepper_sensitivity(self: Self) SensitivityType { 96 | return @intToEnum(SensitivityType, c.gtk_range_get_upper_stepper_sensitivity(self.ptr)); 97 | } 98 | 99 | pub fn get_flippable(self: Self) bool { 100 | return (c.gtk_range_get_flippable(self.ptr) == 1); 101 | } 102 | 103 | pub fn set_flippable(self: Self, flippable: bool) void { 104 | c.gtk_range_set_flippable(self.ptr, if (flippable) 1 else 0); 105 | } 106 | 107 | pub fn connect_value_changed(self: Self, callback: c.GCallback, data: ?c.gpointer) void { 108 | self.as_widget().connect("value_changed", callback, if (data) |d| d else null); 109 | } 110 | 111 | pub fn as_widget(self: Self) Widget { 112 | return Widget{ 113 | .ptr = @ptrCast(*c.GtkWidget, self.ptr), 114 | }; 115 | } 116 | 117 | pub fn is_instance(gtype: u64) bool { 118 | return (gtype == c.gtk_range_get_type() or Scale.is_instance(gtype) or SpinButton.is_instance(gtype)); 119 | } 120 | }; 121 | 122 | pub const Scale = struct { 123 | ptr: *c.GtkScale, 124 | 125 | pub fn new(orientation: Orientation, adjustment: Adjustment) Scale { 126 | return Scale{ 127 | .ptr = @ptrCast(*c.GtkScale, c.gtk_scale_new(@enumToInt(orientation), adjustment.ptr)), 128 | }; 129 | } 130 | 131 | pub fn new_with_range(orientation: Orientation, min: f64, max: f64, step: f64) Scale { 132 | return Scale{ 133 | .ptr = @ptrCast(*c.GtkScale, c.gtk_scale_new_with_range(@enumToInt(orientation), min, max, step)), 134 | }; 135 | } 136 | 137 | pub fn get_digits(self: Scale) c_int { 138 | return c.gtk_scale_get_digits(self.ptr); 139 | } 140 | 141 | pub fn set_digits(self: Scale, digits: c_int) void { 142 | c.gtk_scale_set_digits(self.ptr, digits); 143 | } 144 | 145 | pub fn get_draw_value(self: Scale) bool { 146 | return (c.gtk_scale_get_draw_value(self.ptr) == 1); 147 | } 148 | 149 | pub fn set_draw_value(self: Scale, draw: bool) void { 150 | c.gtk_scale_set_draw_value(self.ptr, if (draw) 1 else 0); 151 | } 152 | 153 | pub fn get_has_origin(self: Scale) bool { 154 | return (c.gtk_scale_get_has_origin(self.ptr) == 1); 155 | } 156 | 157 | pub fn set_has_origin(self: Scale, origin: bool) void { 158 | c.gtk_scale_set_has_origin(self.ptr, if (origin) 1 else 0); 159 | } 160 | 161 | pub fn get_value_pos(self: Scale) PositionType { 162 | return @intToEnum(PositionType, c.gtk_scale_get_value_pos(self.scale)); 163 | } 164 | 165 | pub fn set_value_pos(self: Scale, pos: PositionType) void { 166 | c.gtk_scale_set_value_pos(self.ptr, @enumToInt(pos)); 167 | } 168 | 169 | pub fn add_mark(self: Scale, value: f64, pos: PositionType, markup: ?[:0]const u8) void { 170 | c.gtk_scale_add_mark(self.ptr, value, @enumToInt(pos), if (markup) |t| t.ptr else null); 171 | } 172 | 173 | pub fn clear_marks(self: Scale) void { 174 | c.gtk_scale_clear_marks(self.ptr); 175 | } 176 | 177 | pub fn as_orientable(self: Scale) Orientable { 178 | return Orientable{ 179 | .ptr = @ptrCast(*c.GtkOrientable, self.ptr), 180 | }; 181 | } 182 | 183 | pub fn as_range(self: Scale) Range { 184 | return Range{ 185 | .ptr = @ptrCast(*c.GtkRange, self.ptr), 186 | }; 187 | } 188 | 189 | pub fn as_widget(self: Scale) Widget { 190 | return Widget{ 191 | .ptr = @ptrCast(*c.GtkWidget, self.ptr), 192 | }; 193 | } 194 | 195 | pub fn is_instance(gtype: u64) bool { 196 | return (gtype == c.gtk_scale_get_type()); 197 | } 198 | }; 199 | 200 | pub const SpinButton = struct { 201 | ptr: *c.GtkSpinButton, 202 | 203 | const Self = @This(); 204 | 205 | pub const Increments = struct { 206 | step: f64, 207 | page: f64, 208 | }; 209 | 210 | pub const Bounds = struct { 211 | min: f64, 212 | max: f64, 213 | }; 214 | 215 | pub fn configure(self: Self, adjustment: Adjustment, climb_rate: f64, digits: c_uint) void { 216 | c.gtk_spin_button_configure(self.ptr, adjustment.ptr, climb_rate, digits); 217 | } 218 | 219 | pub fn new(adjustment: Adjustment, climb_rate: f64, digits: c_uint) Self { 220 | return Self{ 221 | .ptr = @ptrCast(*c.GtkSpinButton, c.gtk_spin_button_new(adjustment.ptr, climb_rate, digits)), 222 | }; 223 | } 224 | 225 | pub fn new_with_range(min: f64, max: f64, step: f64) Self { 226 | return Self{ 227 | .ptr = c.gtk_spin_button_new_with_range(min, max, step), 228 | }; 229 | } 230 | 231 | pub fn set_adjustment(self: Self, adjustment: Adjustment) void { 232 | c.gtk_spin_button_set_adjustment(self.ptr, adjustment.ptr); 233 | } 234 | 235 | pub fn get_adjustment(self: Self) Adjustment { 236 | return Adjustment{ 237 | .ptr = c.gtk_spin_button_get_adjustment(self.ptr), 238 | }; 239 | } 240 | 241 | pub fn set_digits(self: Self, digits: c_uint) void { 242 | c.gtk_spin_button_set_digits(self.ptr, digits); 243 | } 244 | 245 | pub fn set_increments(self: Self, step: f64, page: f64) void { 246 | c.gtk_spin_button_set_increments(self.ptr, step, page); 247 | } 248 | 249 | pub fn set_range(self: Self, min: f64, max: f64) void { 250 | c.gtk_spin_button_set_range(self.ptr, min, max); 251 | } 252 | 253 | pub fn get_value_as_int(self: Self) c_int { 254 | return c.gtk_spin_button_get_value_as_int(self.ptr); 255 | } 256 | 257 | pub fn set_value(self: Self, value: f64) void { 258 | c.gtk_spin_button_set_value(self.ptr, value); 259 | } 260 | 261 | pub fn set_update_policy(self: Self, policy: SpinButtonUpdatePolicy) void { 262 | c.gtk_spin_button_set_update_policy(self.ptr, @enumToInt(policy)); 263 | } 264 | 265 | pub fn set_numeric(self: Self, numeric: bool) void { 266 | c.gtk_spin_button_set_numeric(self.ptr, if (numeric) 1 else 0); 267 | } 268 | 269 | pub fn spin(self: Self, direction: SpinType, increment: f64) void { 270 | c.gtk_spin_button_spin(self.ptr, @enumToInt(direction), increment); 271 | } 272 | 273 | pub fn set_wrap(self: Self, wrap: bool) void { 274 | c.gtk_spin_button_set_wrap(self.ptr, if (wrap) 1 else 0); 275 | } 276 | 277 | pub fn set_snap_to_ticks(self: Self, snap: bool) void { 278 | c.gtk_spin_button_set_snap_to_ticks(self.ptr, if (snap) 1 else 0); 279 | } 280 | 281 | pub fn update(self: Self) void { 282 | c.gtk_spin_button_update(self.ptr); 283 | } 284 | 285 | pub fn get_digits(self: Self) c_uint { 286 | return c.gtk_spin_button_get_digits(self.ptr); 287 | } 288 | 289 | pub fn get_increments(self: Self) Increments { 290 | var step: f64 = 0; 291 | var page: f64 = 0; 292 | c.gtk_spin_button_get_increments(self.ptr, step, page); 293 | return Increments{ .step = step, .page = page }; 294 | } 295 | 296 | pub fn get_numeric(self: Self) bool { 297 | return (c.gtk_spin_button_get_numeric(self.ptr) == 1); 298 | } 299 | 300 | pub fn get_range(self: Self) Bounds { 301 | var min: f64 = 0; 302 | var max: f64 = 0; 303 | c.gtk_spin_button_get_range(self.ptr, min, max); 304 | return Bounds{ .min = min, .max = max }; 305 | } 306 | 307 | pub fn get_snap_to_ticks(self: Self) bool { 308 | return (c.gtk_spin_button_get_snap_to_ticks(self.ptr) == 1); 309 | } 310 | 311 | pub fn get_update_policy(self: Self) SpinButtonUpdatePolicy { 312 | return @intToEnum(SpinButtonUpdatePolicy, c.gtk_spin_button_get_update_policy(self.ptr)); 313 | } 314 | 315 | pub fn get_value(self: Self) f64 { 316 | return c.gtk_spin_button_get_value(self.ptr); 317 | } 318 | 319 | pub fn get_wrap(self: Self) bool { 320 | return (c.gtk_spin_button_get_wrap(self.ptr) == 1); 321 | } 322 | 323 | pub fn connect_value_changed(self: Self, callback: c.GCallback, data: ?c.gpointer) void { 324 | self.as_widget().connect("value_changed", callback, if (data) |d| d else null); 325 | } 326 | 327 | pub fn as_range(self: Self) Range { 328 | return Range{ 329 | .ptr = @ptrCast(*c.GtkRange, self.ptr), 330 | }; 331 | } 332 | 333 | pub fn as_widget(self: Self) Widget { 334 | return Widget{ 335 | .ptr = @ptrCast(*c.GtkWidget, self.ptr), 336 | }; 337 | } 338 | 339 | pub fn is_instance(gtype: u64) bool { 340 | return (gtype == c.gtk_spin_button_get_type()); 341 | } 342 | }; 343 | -------------------------------------------------------------------------------- /src/revealer.zig: -------------------------------------------------------------------------------- 1 | const c = @import("cimport.zig"); 2 | const common = @import("common.zig"); 3 | const Container = @import("container.zig").Container; 4 | const Widget = @import("widget.zig").Widget; 5 | 6 | const std = @import("std"); 7 | const fmt = std.fmt; 8 | const mem = std.mem; 9 | 10 | pub const Revealer = struct { 11 | ptr: *c.GtkRevealer, 12 | 13 | const Self = @This(); 14 | 15 | pub fn new() Self { 16 | return Self{ 17 | .ptr = @ptrCast(*c.GtkRevealer, c.gtk_revealer_new()), 18 | }; 19 | } 20 | 21 | pub fn get_reveal_child(self: Self) bool { 22 | return (c.gtk_revealer_get_reveal_child(self.ptr) == 1); 23 | } 24 | 25 | pub fn set_reveal_child(self: Self, reveal: bool) void { 26 | c.gtk_revealer_set_reveal_child(self.ptr, if (reveal) 1 else 0); 27 | } 28 | 29 | pub fn get_child_revealed(self: Self) bool { 30 | return (c.gtk_revealer_get_child_revealed(self.ptr) == 1); 31 | } 32 | 33 | pub fn get_transition_duration(self: Self) c_uint { 34 | return c.gtk_revealer_get_transition_duration(self.ptr); 35 | } 36 | 37 | pub fn set_transition_duration(self: Self, duration: c_uint) void { 38 | c.gtk_revealer_set_transition_duration(self.ptr, duration); 39 | } 40 | 41 | pub fn get_transition_type(self: Self) TransitionType { 42 | return c.gtk_revealer_get_transition_type(self.ptr); 43 | } 44 | 45 | pub fn set_transition_type(self: Self, transition: TransitionType) void { 46 | c.gtk_revealer_set_transition_type(self.ptr, @enumToInt(transition)); 47 | } 48 | 49 | pub fn as_container(self: Self) Widget { 50 | return Widget{ 51 | .ptr = @ptrCast(*c.GtkContainer, self.ptr), 52 | }; 53 | } 54 | 55 | pub fn as_widget(self: Self) Widget { 56 | return Widget{ 57 | .ptr = @ptrCast(*c.GtkWidget, self.ptr), 58 | }; 59 | } 60 | 61 | pub fn is_instance(gtype: u64) bool { 62 | return (gtype == c.gtk_revealer_get_type()); 63 | } 64 | }; 65 | 66 | pub const TransitionType = enum(c_uint) { 67 | none = c.GTK_REVEALER_TRANSITION_TYPE_NONE, 68 | crossfade = c.GTK_REVEALER_TRANSITION_TYPE_CROSSFADE, 69 | slide_right = c.GTK_REVEALER_TRANSITION_TYPE_SLIDE_RIGHT, 70 | slide_left = c.GTK_REVEALER_TRANSITION_TYPE_SLIDE_LEFT, 71 | slide_up = c.GTK_REVEALER_TRANSITION_TYPE_SLIDE_UP, 72 | slide_down = c.GTK_REVEALER_TRANSITION_TYPE_DOWN, 73 | }; 74 | -------------------------------------------------------------------------------- /src/scrollable.zig: -------------------------------------------------------------------------------- 1 | const c = @import("cimport.zig"); 2 | const Adjustment = @import("adjustment.zig").Adjustment; 3 | const Buildable = @import("buildable.zig").Buildable; 4 | const Container = @import("container.zig").Container; 5 | const Widget = @import("widget.zig").Widget; 6 | 7 | /// GtkScrollable is an interface that is implemented by widgets with native 8 | /// scrolling ability. 9 | /// 10 | /// To implement this interface you should override the “hadjustment” and 11 | /// “vadjustment” properties. 12 | /// ### Creating a scrollable widget 13 | /// All scrollable widgets should do the following. 14 | /// * When a parent widget sets the scrollable child widget’s adjustments, the widget should populate the adjustments’ “lower”, “upper”, “step-increment”, “page-increment” and “page-size” properties and connect to the “value-changed” signal. 15 | /// * Because its preferred size is the size for a fully expanded widget, the scrollable widget must be able to cope with underallocations. This means that it must accept any value passed to its GtkWidgetClass.size_allocate() function. 16 | /// * When the parent allocates space to the scrollable child widget, the widget should update the adjustments’ properties with new values. 17 | /// * When any of the adjustments emits the “value-changed” signal, the scrollable widget should scroll its contents. 18 | pub const Scrollable = struct { 19 | ptr: *c.GtkScrollable, 20 | 21 | const Self = @This(); 22 | 23 | /// Defines the policy to be used in a scrollable widget when updating the 24 | /// scrolled window adjustments in a given orientation. 25 | pub const Policy = enum(c_uint) { 26 | /// Scrollable adjustments are based on the minimum size 27 | minimum = c.GTK_SCROLL_MINIMUM, 28 | /// Scrollable adjustments are based on the natural size 29 | natural = c.GTK_SCROLL_NATURAL, 30 | }; 31 | 32 | /// Retrieves the GtkAdjustment used for horizontal scrolling. 33 | pub fn get_hadjustment(self: Self) Adjustment { 34 | return Adjustment{ 35 | .ptr = c.gtk_scrollable_get_hadjustment(self.ptr), 36 | }; 37 | } 38 | 39 | /// Sets the horizontal adjustment of the GtkScrollable. 40 | pub fn set_hadjustment(self: Self, adjustment: Adjustment) void { 41 | c.gtk_scrollable_set_hadjustment(self.ptr, adjustment.ptr); 42 | } 43 | 44 | /// Retrieves the GtkAdjustment used for vertical scrolling. 45 | pub fn get_vadjustment(self: Self) Adjustment { 46 | return Adjustment{ 47 | .ptr = c.gtk_scrollable_get_vadjustment(self.ptr), 48 | }; 49 | } 50 | 51 | /// Sets the vertical adjustment of the GtkScrollable. 52 | pub fn set_vadjustment(self: Self, adjustment: Adjustment) void { 53 | c.gtk_scrollable_set_vadjustment(self.ptr, adjustment.ptr); 54 | } 55 | 56 | /// Gets the horizontal GtkScrollablePolicy. 57 | pub fn get_hscroll_policy(self: Self) Policy { 58 | return @intToEnum(Policy, c.gtk_scrollable_get_hscroll_policy(self.ptr)); 59 | } 60 | 61 | /// Sets the horizontal GtkScrollablePolicy. 62 | pub fn set_hscroll_policy(self: Self) Policy { 63 | return @intToEnum(Policy, c.gtk_scrollable_set_hscroll_policy(self.ptr)); 64 | } 65 | 66 | /// Gets the vertical GtkScrollablePolicy. 67 | pub fn get_vscroll_policy(self: Self) Policy { 68 | return @intToEnum(Policy, c.gtk_scrollable_get_vscroll_policy(self.ptr)); 69 | } 70 | 71 | /// Sets the vertical GtkScrollablePolicy. 72 | pub fn set_vscroll_policy(self: Self) Policy { 73 | return @intToEnum(Policy, c.gtk_scrollable_set_vscroll_policy(self.ptr)); 74 | } 75 | 76 | /// Returns the size of a non-scrolling border around the outside of the 77 | /// scrollable. An example for this would be treeview headers. GTK+ can use 78 | /// this information to display overlayed graphics, like the overshoot 79 | /// indication, at the right position. 80 | pub fn get_border(self: Self) ?c.GtkBorder { 81 | var border = c.GtkBorder{ 82 | .left = 0, 83 | .right = 0, 84 | .top = 0, 85 | .bottom = 0, 86 | }; 87 | return if (c.gtk_scrollable_get_border(self.ptr, &border) == 1) border else null; 88 | } 89 | 90 | pub fn is_instance(gtype: u64) bool { 91 | return (gtype == c.gtk_scrollable_get_type()); 92 | } 93 | }; 94 | -------------------------------------------------------------------------------- /src/separator.zig: -------------------------------------------------------------------------------- 1 | const c = @import("cimport.zig"); 2 | const Buildable = @import("buildable.zig").Buildable; 3 | const Orientable = @import("orientable.zig").Orientable; 4 | const Orientation = @import("enums.zig").Orientation; 5 | const Widget = @import("widget.zig").Widget; 6 | 7 | /// GtkSeparator is a horizontal or vertical separator widget, depending on 8 | /// the value of the “orientation” property, used to group the widgets 9 | /// within a window. It displays a line with a shadow to make it appear 10 | /// sunken into the interface. 11 | /// ### CSS 12 | /// GtkSeparator has a single CSS node with name separator. The node gets 13 | /// one of the .horizontal or .vertical style classes. 14 | pub const Separator = struct { 15 | ptr: *c.GtkSeparator, 16 | 17 | const Self = @This(); 18 | 19 | /// Creates a new GtkSeparator with the given orientation. 20 | pub fn new(orientation: Orientation) Self { 21 | return Self{ 22 | .ptr = @ptrCast(*c.GtkSeparator, c.gtk_separator_new(@enumToInt(orientation))), 23 | }; 24 | } 25 | 26 | pub fn as_buildable(self: Self) Buildable { 27 | return Buildable{ 28 | .ptr = @ptrCast(*c.GtkBuildable, self.ptr), 29 | }; 30 | } 31 | 32 | pub fn as_orientable(self: Self) Orientable { 33 | return Orientable{ 34 | .ptr = @ptrCast(*c.GtkOrientable, self.ptr), 35 | }; 36 | } 37 | 38 | pub fn as_widget(self: Self) Widget { 39 | return Widget{ 40 | .ptr = @ptrCast(*c.GtkWidget, self.ptr), 41 | }; 42 | } 43 | 44 | pub fn is_instance(gtype: u64) bool { 45 | return (gtype == c.gtk_separator_get_type()); 46 | } 47 | }; 48 | -------------------------------------------------------------------------------- /src/spinner.zig: -------------------------------------------------------------------------------- 1 | const c = @import("cimport.zig"); 2 | const Widget = @import("widget.zig").Widget; 3 | 4 | const std = @import("std"); 5 | 6 | pub const Spinner = struct { 7 | ptr: *c.GtkSpinner, 8 | 9 | const Self = @This(); 10 | 11 | pub fn new() Self { 12 | return Self{ 13 | .ptr = @ptrCast(*c.GtkSpinner, c.gtk_spinner_new()), 14 | }; 15 | } 16 | 17 | pub fn start(self: Self) void { 18 | c.gtk_spinner_start(self.ptr); 19 | } 20 | 21 | pub fn stop(self: Self) void { 22 | c.gtk_spinner_stop(self.ptr); 23 | } 24 | 25 | pub fn as_widget(self: Self) Widget { 26 | return Widget{ .ptr = @ptrCast(*c.GtkWidget, self.ptr) }; 27 | } 28 | 29 | pub fn is_instance(gtype: u64) bool { 30 | return (gtype == c.gtk_spinner_get_type()); 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /src/stack.zig: -------------------------------------------------------------------------------- 1 | const c = @import("cimport.zig"); 2 | const com = @import("common.zig"); 3 | const Bin = @import("bin.zig").Bin; 4 | const Box = @import("box.zig").Box; 5 | const Container = @import("container.zig").Container; 6 | const Orientable = @import("orientable.zig").Orientable; 7 | const Widget = @import("widget.zig").Widget; 8 | 9 | const std = @import("std"); 10 | const fmt = std.fmt; 11 | const mem = std.mem; 12 | 13 | pub const Stack = struct { 14 | ptr: *c.GtkStack, 15 | 16 | const Self = @This(); 17 | 18 | pub fn new() Self { 19 | return Self{ 20 | .ptr = @ptrCast(*c.GtkStack, c.gtk_stack_new()), 21 | }; 22 | } 23 | 24 | pub fn add_named(self: Self, child: Widget, name: [:0]const u8) void { 25 | c.gtk_stack_add_named(self.ptr, child.ptr, name.ptr); 26 | } 27 | 28 | pub fn add_titled(self: Self, child: Widget, name: [:0]const u8, title: [:0]const u8) void { 29 | c.gtk_stack_add_titled(self.ptr, child.ptr, name, title.ptr); 30 | } 31 | 32 | pub fn get_child_by_name(self: Self, name: [:0]const u8) ?Widget { 33 | return if (c.gtk_stack_get_child_by_name(self.ptr, name.ptr)) |w| Widget{ 34 | .ptr = w, 35 | } else null; 36 | } 37 | 38 | pub fn set_visible_child(self: Self, child: Widget) void { 39 | c.gtk_stack_set_visible_child(self.ptr, child.ptr); 40 | } 41 | 42 | pub fn get_visible_child(self: Self) ?Widget { 43 | return if (c.gtk_stack_get_visible_child(self.ptr)) |w| Widget{ 44 | .ptr = w, 45 | } else null; 46 | } 47 | 48 | pub fn set_visible_child_name(self: Self, child: [:0]const u8) void { 49 | c.gtk_stack_set_visible_child_name(self.ptr, child.ptr); 50 | } 51 | 52 | pub fn get_visible_child_name(self: Self) ?[:0]const u8 { 53 | return if (c.gtk_stack_get_visible_child_name(self.ptr)) |w| Widget{ 54 | .ptr = w, 55 | } else null; 56 | } 57 | 58 | pub fn set_visible_child_full(self: Self, name: [:0]const u8, transition: StackTransitionStyle) void { 59 | c.gtk_stack_set_visible_child_full(self.ptr, name.ptr, @enumToInt(transition)); 60 | } 61 | 62 | pub fn set_homogeneous(self: Self, hom: bool) void { 63 | c.gtk_stack_set_homogeneous(self.ptr, if (hom) 1 else 0); 64 | } 65 | 66 | pub fn get_homogeneous(self: Self) bool { 67 | return (c.gtk_stack_get_homeogeneous(self.ptr) == 1); 68 | } 69 | 70 | pub fn set_hhomogeneous(self: Self, hom: bool) void { 71 | c.gtk_stack_set_hhomogeneous(self.ptr, if (hom) 1 else 0); 72 | } 73 | 74 | pub fn get_hhomogeneous(self: Self) bool { 75 | return (c.gtk_stack_get_hhomeogeneous(self.ptr) == 1); 76 | } 77 | 78 | pub fn set_vhomogeneous(self: Self, hom: bool) void { 79 | c.gtk_stack_set_vhomogeneous(self.ptr, if (hom) 1 else 0); 80 | } 81 | 82 | pub fn get_vhomogeneous(self: Self) bool { 83 | return (c.gtk_stack_get_vhomeogeneous(self.ptr) == 1); 84 | } 85 | 86 | pub fn set_transition_duration(self: Self, duration: c_uint) void { 87 | c.gtk_stack_set_transition_duration(self.ptr, duration); 88 | } 89 | 90 | pub fn get_transition_duration(self: Self) c_uint { 91 | return c.gtk_stack_get_transition_duration(self.ptr); 92 | } 93 | 94 | pub fn set_transition_type(self: Self, transition: StackTransitionStyle) void { 95 | c.gtk_stack_set_transition_type(self.ptr, @enumToInt(transition)); 96 | } 97 | 98 | pub fn get_transition_type(self: Self) StackTransitionStyle { 99 | return @intToEnum(StackTransitionStyle, c.gtk_stack_get_transition_type(self.ptr)); 100 | } 101 | 102 | pub fn get_transition_running(self: Self) bool { 103 | return (c.gtk_stack_get_transition_running(self.ptr) == 1); 104 | } 105 | 106 | pub fn get_interpolate_size(self: Self) bool { 107 | return (c.gtk_stack_get_interpolate_size(self.ptr) == 1); 108 | } 109 | 110 | pub fn set_interpolate_size(self: Self, interpolate_size: bool) void { 111 | c.gtk_stack_set_interpolate_size(self.ptr, if (interpolate_size) 1 else 0); 112 | } 113 | 114 | pub fn as_container(self: Self) Container { 115 | return Container{ 116 | .ptr = @ptrCast(*c.GtkContainer, self.ptr), 117 | }; 118 | } 119 | 120 | pub fn as_widget(self: Self) Widget { 121 | return Widget{ 122 | .ptr = @ptrCast(*c.GtkWidget, self.ptr), 123 | }; 124 | } 125 | 126 | pub fn is_instance(gtype: u64) bool { 127 | return (gtype == c.gtk_stack_get_type()); 128 | } 129 | }; 130 | 131 | pub const StackSwitcher = struct { 132 | ptr: *c.GtkStackSwitcher, 133 | 134 | const Self = @This(); 135 | 136 | pub fn new() Self { 137 | return Self{ .ptr = @ptrCast(*c.GtkStackSwitcher, c.gtk_stack_switcher_new()) }; 138 | } 139 | 140 | pub fn set_stack(self: Self, stack: Stack) void { 141 | c.gtk_stack_switcher_set_stack(self.ptr, stack.ptr); 142 | } 143 | 144 | pub fn get_stack(self: Self) Stack { 145 | return Stack{ .ptr = c.gtk_stack_switcher_get_stack(self.ptr) }; 146 | } 147 | 148 | pub fn as_box(self: Self) Box { 149 | return Box{ 150 | .ptr = @ptrCast(*c.GtkBox, self.ptr), 151 | }; 152 | } 153 | 154 | pub fn as_container(self: Self) Container { 155 | return Container{ 156 | .ptr = @ptrCast(*c.GtkContainer, self.ptr), 157 | }; 158 | } 159 | 160 | pub fn as_orientable(self: Self) Orientable { 161 | return Orientable{ 162 | .ptr = @ptrCast(*c.GtkOrientable, self.ptr), 163 | }; 164 | } 165 | 166 | pub fn as_widget(self: Self) Widget { 167 | return Widget{ 168 | .ptr = @ptrCast(*c.GtkWidget, self.ptr), 169 | }; 170 | } 171 | 172 | pub fn is_instance(gtype: u64) bool { 173 | return (gtype == c.gtk_stack_switcher_get_type()); 174 | } 175 | }; 176 | 177 | pub const StackSidebar = struct { 178 | ptr: *c.GtkStackSidebar, 179 | 180 | const Self = @This(); 181 | 182 | pub fn new() Self { 183 | return Self{ 184 | .ptr = @ptrCast(*c.GtkStackSidebar, c.gtk_stack_sidebar_new()), 185 | }; 186 | } 187 | 188 | pub fn set_stack(self: Self, stack: Stack) void { 189 | c.gtk_stack_sidebar_set_stack(self.ptr, stack.ptr); 190 | } 191 | 192 | pub fn get_stack(self: Self) Stack { 193 | return Stack{ .ptr = c.gtk_stack_sidebar_get_stack(self.ptr) }; 194 | } 195 | 196 | pub fn as_bin(self: Self) Bin { 197 | return Bin{ .ptr = @ptrCast(*c.GtkBin, self.ptr) }; 198 | } 199 | 200 | pub fn as_container(self: Self) Container { 201 | return Container{ 202 | .ptr = @ptrCast(*c.GtkContainer, self.ptr), 203 | }; 204 | } 205 | 206 | pub fn as_widget(self: Self) Widget { 207 | return Widget{ 208 | .ptr = @ptrCast(*c.GtkWidget, self.ptr), 209 | }; 210 | } 211 | 212 | pub fn is_instance(gtype: u64) bool { 213 | return (gtype == c.gtk_stack_sidebar_get_type()); 214 | } 215 | }; 216 | 217 | /// enum StackTransitionStyle 218 | pub const StackTransitionStyle = enum(c_uint) { 219 | none = c.GTK_STACK_TRANSITION_TYPE_NONE, 220 | crossfade = c.GTK_STACK_TRANSITION_TYPE_CROSSFADE, 221 | slide_right = c.GTK_STACK_TRANSITION_TYPE_RIGHT, 222 | slide_left = c.GTK_STACK_TRANSITION_TYPE_LEFT, 223 | slide_up = c.GTK_STACK_TRANSITION_TYPE_UP, 224 | slide_down = c.GTK_STACK_TRANSITION_TYPE_DOWN, 225 | slide_left_right = c.GTK_STACK_TRANSITION_TYPE_LEFT_RIGHT, 226 | slide_up_down = c.GTK_STACK_TRANSITION_TYPE_UP_DOWN, 227 | over_up = c.GTK_STACK_TRANSITION_TYPE_OVER_UP, 228 | over_down = c.GTK_STACK_TRANSITION_TYPE_OVER_DOWN, 229 | over_left = c.GTK_STACK_TRANSITION_TYPE_OVER_LEFT, 230 | over_right = c.GTK_STACK_TRANSITION_TYPE_OVER_RIGHT, 231 | under_up = c.GTK_STACK_TRANSITION_TYPE_UNDER_UP, 232 | under_down = c.GTK_STACK_TRANSITION_TYPE_UNDER_DOWN, 233 | under_left = c.GTK_STACK_TRANSITION_TYPE_UNDER_LEFT, 234 | under_right = c.GTK_STACK_TRANSITION_TYPE_UNDER_RIGHT, 235 | over_up_down = c.GTK_STACK_TRANSITION_TYPE_OVER_UP_DOWN, 236 | over_down_up = c.GTK_STACK_TRANSITION_TYPE_OVER_DOWN_UP, 237 | over_left_right = c.GTK_STACK_TRANSITION_TYPE_OVER_LEFT_RIGHT, 238 | over_right_left = c.GTK_STACK_TRANSITION_TYPE_OVER_RIGHT_LEFT, 239 | }; 240 | -------------------------------------------------------------------------------- /src/switch.zig: -------------------------------------------------------------------------------- 1 | const c = @import("cimport.zig"); 2 | 3 | const Actionable = @import("actionable.zig").Actionable; 4 | const Widget = @import("widget.zig").Widget; 5 | 6 | pub const Switch = struct { 7 | ptr: *c.GtkSwitch, 8 | 9 | const Self = @This(); 10 | 11 | // Creates a new Switch 12 | pub fn new() Self { 13 | return Self{ 14 | .ptr = c.gtk_switch_new(), 15 | }; 16 | } 17 | 18 | // Gets whether the Switch is in it's "on" or "off" state 19 | pub fn get_active(self: Self) bool { 20 | return (c.gtk_switch_get_active(self.ptr) == 1); 21 | } 22 | 23 | // Sets the state of Switch on or off 24 | pub fn set_active(self: Self, state: bool) void { 25 | c.gtk_switch_set_active(self.ptr, if (state) 1 else 0); 26 | } 27 | 28 | pub fn connect_state_set(self: Self, callback: c.GCallback, data: ?c.gpointer) void { 29 | self.as_widget().connect("state_set", callback, if (data) |d| d else null); 30 | } 31 | 32 | pub fn as_actionable(self: Self) Actionable { 33 | return Actionable{ 34 | .ptr = @ptrCast(*c.GtkActionable, self.ptr), 35 | }; 36 | } 37 | 38 | pub fn as_widget(self: Self) Widget { 39 | return Widget{ 40 | .ptr = @ptrCast(*c.GtkWidget, self.ptr), 41 | }; 42 | } 43 | 44 | pub fn is_instance(gtype: u64) bool { 45 | return (gtype == c.gtk_switch_get_type()); 46 | } 47 | }; 48 | -------------------------------------------------------------------------------- /src/window.zig: -------------------------------------------------------------------------------- 1 | const c = @import("cimport.zig"); 2 | const common = @import("common.zig"); 3 | const bool_to_c_int = common.bool_to_c_int; 4 | const Container = @import("container.zig").Container; 5 | const Dialog = @import("dialog.zig").Dialog; 6 | const WindowType = @import("enums.zig").WindowType; 7 | const Widget = @import("widget.zig").Widget; 8 | 9 | pub const ApplicationWindow = struct { 10 | ptr: *c.GtkApplicationWindow, 11 | 12 | pub fn new(app: *c.GtkApplication) ApplicationWindow { 13 | return ApplicationWindow{ 14 | .ptr = @ptrCast(*c.GtkApplicationWindow, c.gtk_application_window_new(app)), 15 | }; 16 | } 17 | 18 | pub fn as_window(self: ApplicationWindow) Window { 19 | return Window{ 20 | .ptr = @ptrCast(*c.GtkWindow, self.ptr), 21 | }; 22 | } 23 | 24 | pub fn as_container(self: ApplicationWindow) Container { 25 | return Container{ 26 | .ptr = @ptrCast(*c.GtkContainer, self.ptr), 27 | }; 28 | } 29 | 30 | pub fn as_widget(self: ApplicationWindow) Widget { 31 | return Widget{ 32 | .ptr = @ptrCast(*c.GtkWidget, self.ptr), 33 | }; 34 | } 35 | 36 | pub fn is_instance(gtype: u64) bool { 37 | return (gtype == c.gtk_application_window_get_type()); 38 | } 39 | }; 40 | 41 | pub const Window = struct { 42 | ptr: *c.GtkWindow, 43 | 44 | const Self = @This(); 45 | 46 | pub fn new(window_type: WindowType) Self { 47 | return Self{ 48 | .ptr = @ptrCast(*c.GtkWindow, c.gtk_window_new(@enumToInt(window_type))), 49 | }; 50 | } 51 | 52 | pub fn set_title(self: Self, title: [:0]const u8) void { 53 | c.gtk_window_set_title(self.ptr, title.ptr); 54 | } 55 | 56 | pub fn set_default_size(self: Self, hsize: c_int, vsize: c_int) void { 57 | c.gtk_window_set_default_size(self.ptr, hsize, vsize); 58 | } 59 | 60 | pub fn set_decorated(self: Self, decorated: bool) void { 61 | const val = bool_to_c_int(decorated); 62 | c.gtk_window_set_decorated(self.ptr, val); 63 | } 64 | 65 | pub fn close(self: Self) void { 66 | c.gtk_window_close(self.ptr); 67 | } 68 | 69 | pub fn set_transient_for(self: Self, parent: Self) void { 70 | c.gtk_window_set_transient_for(self.ptr, parent.ptr); 71 | } 72 | 73 | pub fn as_container(self: Self) Container { 74 | return Container{ 75 | .ptr = @ptrCast(*c.GtkContainer, self.ptr), 76 | }; 77 | } 78 | 79 | pub fn as_widget(self: Self) Widget { 80 | return Widget{ 81 | .ptr = @ptrCast(*c.GtkWidget, self.ptr), 82 | }; 83 | } 84 | 85 | pub fn is_instance(gtype: u64) bool { 86 | return (gtype == c.gtk_window_get_type() or ApplicationWindow.is_instance(gtype) or Dialog.is_instance(gtype)); 87 | } 88 | }; 89 | -------------------------------------------------------------------------------- /zigmod.yml: -------------------------------------------------------------------------------- 1 | id: y7bq9a3u4z6cczlzzzocxe6j59eohj1pgy0f25atirxz1659 2 | name: gtk3 3 | main: lib.zig 4 | license: MIT 5 | description: Gtk+ version 3 bindings for Zig 6 | dependencies: 7 | --------------------------------------------------------------------------------