This commit is contained in:
Julian Ospald 2017-07-04 21:15:11 +02:00
parent 64367bb187
commit 8907a2005c
No known key found for this signature in database
GPG Key ID: 511B62C09D50CD28
9 changed files with 616 additions and 455 deletions

View File

@ -16,6 +16,10 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">start</property>
<property name="margin_start">5</property>
<property name="margin_end">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkFrame" id="frame9">
@ -24,28 +28,13 @@
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkTable" id="table8">
<object class="GtkGrid" id="noti_options_grid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_start">12</property>
<property name="n_rows">2</property>
<property name="n_columns">2</property>
<property name="row_spacing">15</property>
<child>
<object class="GtkCheckButton" id="noti_enable_check">
<property name="label" translatable="yes">Enable Notifications</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="halign">start</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="on_noti_enable_check_toggled" swapped="no"/>
</object>
<packing>
<property name="y_options">GTK_EXPAND</property>
</packing>
</child>
<property name="row_spacing">6</property>
<property name="column_spacing">12</property>
<property name="column_homogeneous">True</property>
<child>
<object class="GtkLabel" id="noti_timeout_label">
<property name="visible">True</property>
@ -54,9 +43,8 @@
<property name="label" translatable="yes">Timeout (ms):</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options">GTK_EXPAND</property>
</packing>
</child>
<child>
@ -69,10 +57,23 @@
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options">GTK_EXPAND</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="noti_enable_check">
<property name="label" translatable="yes">Enable Notifications</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="halign">start</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="on_noti_enable_check_toggled" swapped="no"/>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
@ -198,6 +199,10 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">start</property>
<property name="margin_start">5</property>
<property name="margin_end">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel" id="noti_disabled_label">
@ -333,6 +338,51 @@
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="apply_button">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<child>
<object class="GtkBox" id="box4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<child>
<object class="GtkImage" id="image4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-apply</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label30">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_start">5</property>
<property name="label" translatable="yes">Apply</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
@ -346,10 +396,142 @@
<property name="can_focus">True</property>
<property name="show_border">False</property>
<child>
<object class="GtkBox" id="vbox2">
<object class="GtkBox" id="device_vbox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">start</property>
<property name="margin_start">5</property>
<property name="margin_end">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkFrame" id="frame3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkGrid" id="device_grid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_start">12</property>
<property name="row_spacing">6</property>
<property name="column_spacing">12</property>
<property name="column_homogeneous">True</property>
<child>
<object class="GtkLabel" id="label10">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Card:</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label11">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Channel:</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label23">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="tooltip_text" translatable="yes">Change volume on a logarithmic scale, closer to human perception.</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Normalize Volume:</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkComboBoxText" id="card_combo">
<property name="visible">True</property>
<property name="can_focus">False</property>
<signal name="changed" handler="on_card_combo_changed" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkComboBoxText" id="chan_combo">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="normalize_vol_check">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
</packing>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label9">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_bottom">5</property>
<property name="label" translatable="yes">&lt;b&gt;Sound Device&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="padding">5</property>
<property name="position">0</property>
</packing>
</child>
</object>
</child>
<child type="tab">
<object class="GtkLabel" id="device_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Device</property>
</object>
<packing>
<property name="tab_fill">False</property>
</packing>
</child>
<child>
<object class="GtkBox" id="view_vbox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">start</property>
<property name="margin_start">5</property>
<property name="margin_end">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkFrame" id="frame1">
@ -358,13 +540,37 @@
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkTable" id="table1">
<object class="GtkGrid" id="volume_popup_grid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_start">12</property>
<property name="n_rows">2</property>
<property name="n_columns">2</property>
<property name="row_spacing">15</property>
<property name="row_spacing">6</property>
<property name="column_spacing">12</property>
<property name="column_homogeneous">True</property>
<child>
<object class="GtkLabel" id="label35">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Slider Orientation:</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="vol_pos_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Text Volume Position:</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="vol_text_check">
<property name="label" translatable="yes">Display Text Volume</property>
@ -377,21 +583,23 @@
<signal name="toggled" handler="on_vol_text_check_toggled" swapped="no"/>
</object>
<packing>
<property name="right_attach">2</property>
<property name="y_options">GTK_EXPAND</property>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="vol_pos_label">
<object class="GtkComboBoxText" id="vol_orientation_combo">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Text Volume Position:</property>
<property name="active">0</property>
<items>
<item id="vertical" translatable="yes">Vertical</item>
<item id="horizontal" translatable="yes">Horizontal</item>
</items>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options">GTK_EXPAND</property>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
@ -408,12 +616,12 @@
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options">GTK_EXPAND</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<placeholder/>
</child>
</object>
</child>
<child type="label">
@ -440,27 +648,23 @@
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkTable" id="table2">
<object class="GtkGrid" id="volume_meter_grid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_start">12</property>
<property name="n_rows">3</property>
<property name="n_columns">2</property>
<property name="row_spacing">15</property>
<property name="row_spacing">6</property>
<property name="column_spacing">12</property>
<property name="column_homogeneous">True</property>
<child>
<object class="GtkCheckButton" id="vol_meter_draw_check">
<property name="label" translatable="yes">Draw Volume Meter on Tray Icon</property>
<property name="use_action_appearance">False</property>
<object class="GtkLabel" id="vol_meter_color_label">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="on_vol_meter_draw_check_toggled" swapped="no"/>
<property name="label" translatable="yes">Volume Meter Color:</property>
</object>
<packing>
<property name="right_attach">2</property>
<property name="y_options">GTK_EXPAND</property>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
@ -471,22 +675,21 @@
<property name="label" translatable="yes">Volume Meter Offset (%):</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options">GTK_EXPAND</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="vol_meter_color_label">
<object class="GtkColorButton" id="vol_meter_color_button">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Volume Meter Color:</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="rgba">rgb(0,0,0)</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="y_options">GTK_EXPAND</property>
</packing>
</child>
<child>
@ -502,26 +705,24 @@
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options">GTK_EXPAND</property>
</packing>
</child>
<child>
<object class="GtkColorButton" id="vol_meter_color_button">
<object class="GtkCheckButton" id="vol_meter_draw_check">
<property name="label" translatable="yes">Draw Volume Meter on Tray Icon</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="rgba">rgb(0,0,0)</property>
<property name="receives_default">False</property>
<property name="halign">start</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="on_vol_meter_draw_check_toggled" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="y_options">GTK_EXPAND</property>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="width">2</property>
</packing>
</child>
</object>
@ -543,95 +744,30 @@
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<child type="tab">
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">View</property>
</object>
<packing>
<property name="tab_fill">False</property>
</packing>
</child>
<child>
<object class="GtkBox" id="vbox3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">start</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkFrame" id="frame3">
<object class="GtkFrame" id="frame6">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkTable" id="table3">
<object class="GtkCheckButton" id="system_theme">
<property name="label" translatable="yes">Use System Theme</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="halign">start</property>
<property name="margin_start">12</property>
<property name="n_rows">2</property>
<property name="n_columns">2</property>
<property name="row_spacing">15</property>
<child>
<object class="GtkLabel" id="label10">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Card:</property>
</object>
<packing>
<property name="y_options">GTK_EXPAND</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label11">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Channel:</property>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options">GTK_EXPAND</property>
</packing>
</child>
<child>
<object class="GtkComboBoxText" id="card_combo">
<property name="visible">True</property>
<property name="can_focus">False</property>
<signal name="changed" handler="on_card_combo_changed" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="y_options">GTK_EXPAND</property>
</packing>
</child>
<child>
<object class="GtkComboBoxText" id="chan_combo">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options">GTK_EXPAND</property>
</packing>
</child>
<property name="draw_indicator">True</property>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label9">
<object class="GtkLabel" id="label17">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_bottom">5</property>
<property name="label" translatable="yes">&lt;b&gt;Sound Device&lt;/b&gt;</property>
<property name="label" translatable="yes">&lt;b&gt;Icon Theme&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
</child>
@ -640,7 +776,7 @@
<property name="expand">False</property>
<property name="fill">False</property>
<property name="padding">5</property>
<property name="position">0</property>
<property name="position">2</property>
</packing>
</child>
</object>
@ -649,10 +785,10 @@
</packing>
</child>
<child type="tab">
<object class="GtkLabel" id="label2">
<object class="GtkLabel" id="view_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Device</property>
<property name="label" translatable="yes">View</property>
</object>
<packing>
<property name="position">1</property>
@ -660,10 +796,14 @@
</packing>
</child>
<child>
<object class="GtkBox" id="vbox4">
<object class="GtkBox" id="behavior_vbox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">start</property>
<property name="margin_start">5</property>
<property name="margin_end">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkFrame" id="frame4">
@ -705,14 +845,13 @@
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkTable" id="table7">
<object class="GtkGrid" id="volume_scrolling_grid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_start">12</property>
<property name="n_rows">2</property>
<property name="n_columns">2</property>
<property name="column_spacing">5</property>
<property name="row_spacing">15</property>
<property name="row_spacing">6</property>
<property name="column_spacing">12</property>
<property name="column_homogeneous">True</property>
<child>
<object class="GtkLabel" id="label31">
<property name="visible">True</property>
@ -721,7 +860,8 @@
<property name="label" translatable="yes">Scroll Step:</property>
</object>
<packing>
<property name="y_options">GTK_EXPAND</property>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
@ -732,9 +872,8 @@
<property name="label" translatable="yes">Fine Scroll Step:</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options">GTK_EXPAND</property>
</packing>
</child>
<child>
@ -750,8 +889,7 @@
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="y_options">GTK_EXPAND</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
@ -767,10 +905,7 @@
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options">GTK_EXPAND</property>
</packing>
</child>
</object>
@ -799,25 +934,13 @@
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkTable" id="table4">
<object class="GtkGrid" id="mouse_grid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_start">12</property>
<property name="n_rows">2</property>
<property name="n_columns">2</property>
<property name="column_spacing">5</property>
<property name="row_spacing">15</property>
<child>
<object class="GtkLabel" id="label15">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Middle Click Action:</property>
</object>
<packing>
<property name="y_options">GTK_EXPAND</property>
</packing>
</child>
<property name="row_spacing">6</property>
<property name="column_spacing">12</property>
<property name="column_homogeneous">True</property>
<child>
<object class="GtkLabel" id="custom_label">
<property name="visible">True</property>
@ -826,9 +949,20 @@
<property name="label" translatable="yes">Custom Command:</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options">GTK_EXPAND</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="middle_click_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Middle Click Action:</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
@ -845,8 +979,7 @@
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="y_options">GTK_EXPAND</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
@ -859,10 +992,7 @@
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options">GTK_EXPAND</property>
</packing>
</child>
</object>
@ -890,7 +1020,7 @@
</packing>
</child>
<child type="tab">
<object class="GtkLabel" id="label3">
<object class="GtkLabel" id="behavior_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Behavior</property>
@ -901,10 +1031,14 @@
</packing>
</child>
<child>
<object class="GtkBox" id="vbox5">
<object class="GtkBox" id="hotkeys_vbox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">start</property>
<property name="margin_start">5</property>
<property name="margin_end">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkFrame" id="frame8">
@ -937,13 +1071,12 @@
</packing>
</child>
<child>
<object class="GtkTable" id="hotkeys_table">
<object class="GtkGrid" id="hotkeys_grid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_start">5</property>
<property name="n_rows">5</property>
<property name="n_columns">2</property>
<property name="row_spacing">15</property>
<property name="row_spacing">12</property>
<property name="column_spacing">12</property>
<property name="column_homogeneous">True</property>
<child>
<object class="GtkLabel" id="label20">
<property name="visible">True</property>
@ -954,6 +1087,10 @@
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label7">
@ -963,8 +1100,8 @@
<property name="label" translatable="yes">Mute/Unmute:</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
@ -975,8 +1112,8 @@
<property name="label" translatable="yes">Volume Up:</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
</packing>
</child>
<child>
@ -987,20 +1124,8 @@
<property name="label" translatable="yes">Volume Down:</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label19">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Double-click a HotKey to assign a new HotKey</property>
</object>
<packing>
<property name="right_attach">2</property>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
</packing>
</child>
<child>
@ -1014,7 +1139,7 @@
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
@ -1035,9 +1160,7 @@
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
@ -1058,9 +1181,7 @@
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
</packing>
</child>
<child>
@ -1081,16 +1202,25 @@
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label19">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Double-click a HotKey to assign a new HotKey</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">4</property>
<property name="width">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="padding">5</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
@ -1119,7 +1249,7 @@
</packing>
</child>
<child type="tab">
<object class="GtkLabel" id="label6">
<object class="GtkLabel" id="hotkeys_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">HotKeys</property>
@ -1142,6 +1272,7 @@
<action-widgets>
<action-widget response="-6">cancel_button</action-widget>
<action-widget response="-5">ok_button</action-widget>
<action-widget response="-10">apply_button</action-widget>
</action-widgets>
</object>
</interface>

View File

@ -1,21 +1,19 @@
use alsa::card::Card;
use alsa::mixer::SelemChannelId::*;
use alsa::mixer::{Mixer, Selem, Elem, SelemId};
use alsa::mixer::{Mixer, Selem, SelemId};
use alsa::poll::PollDescriptors;
use alsa;
use alsa_sys;
use errors::*;
use glib_sys;
use libc::c_int;
use libc::c_uint;
use libc::pollfd;
use libc::size_t;
use std::cell::Cell;
use std::iter::Map;
use std::mem;
use std::ptr;
use std::rc::Rc;
use std::u8;
use support_alsa::*;
@ -253,100 +251,3 @@ extern "C" fn watch_cb(
return true as glib_sys::gboolean;
}
pub fn get_default_alsa_card() -> Card {
return get_alsa_card_by_id(0);
}
pub fn get_alsa_card_by_id(index: c_int) -> Card {
return Card::new(index);
}
pub fn get_alsa_cards() -> alsa::card::Iter {
return alsa::card::Iter::new();
}
pub fn get_alsa_card_names() -> Vec<String> {
let mut vec = vec![];
for card in get_alsa_cards() {
match card.and_then(|c| c.get_name()) {
Ok(name) => vec.push(name),
_ => (),
}
}
return vec;
}
pub fn get_alsa_card_by_name(name: String) -> Result<Card> {
for r_card in get_alsa_cards() {
let card = r_card?;
let card_name = card.get_name()?;
if name == card_name {
return Ok(card);
}
}
bail!("Not found a matching card named {}", name);
}
pub fn get_mixer(card: &Card) -> Result<Mixer> {
return Mixer::new(&format!("hw:{}", card.get_index()), false).from_err();
}
pub fn get_selem(elem: Elem) -> Selem {
/* in the ALSA API, there are currently only simple elements,
* so this unwrap() should be safe.
*http://www.alsa-project.org/alsa-doc/alsa-lib/group___mixer.html#enum-members */
return Selem::new(elem).unwrap();
}
pub fn get_selems(mixer: &Mixer) -> Map<alsa::mixer::Iter, fn(Elem) -> Selem> {
return mixer.iter().map(get_selem);
}
pub fn get_selem_names(mixer: &Mixer) -> Vec<String> {
let mut vec = vec![];
for selem in get_selems(mixer) {
let n = selem.get_id().get_name().map(|y| String::from(y));
match n {
Ok(name) => vec.push(name),
_ => (),
}
}
return vec;
}
pub fn get_selem_by_name(mixer: &Mixer, name: String) -> Result<Selem> {
for selem in get_selems(mixer) {
let n = selem.get_id().get_name().map(|y| String::from(y))?;
if n == name {
return Ok(selem);
}
}
bail!("Not found a matching selem named {}", name);
}
pub fn vol_to_percent(vol: i64, range: (i64, i64)) -> f64 {
let (min, max) = range;
return ((vol - min) as f64) / ((max - min) as f64) * 100.0;
}
pub fn percent_to_vol(vol: f64, range: (i64, i64)) -> i64 {
let (min, max) = range;
let _v = vol / 100.0 * ((max - min) as f64) + (min as f64);
/* TODO: precision? Use direction. */
return _v as i64;
}

View File

@ -1,5 +1,6 @@
use gtk;
use audio::Audio;
use ui_tray_icon::TrayIcon;
@ -30,7 +31,7 @@ impl AppS {
pub struct Gui {
pub status_icon: gtk::StatusIcon,
pub tray_icon: TrayIcon,
pub popup_window: PopupWindow,
pub popup_menu: PopupMenu,
/* prefs_dialog is dynamically created and destroyed */
@ -43,7 +44,7 @@ impl Gui {
builder_popup_menu: gtk::Builder,
) -> Gui {
return Gui {
status_icon: gtk::StatusIcon::new(),
tray_icon: TrayIcon::new().unwrap(),
popup_window: PopupWindow::new(builder_popup_window),
popup_menu: PopupMenu::new(builder_popup_menu),
};

View File

@ -1,11 +1,11 @@
use alsa_card::*;
use errors::*;
use glib;
use std::cell::Cell;
use std::cell::Ref;
use std::cell::RefCell;
use std::rc::Rc;
use std::f64;
use alsa_pn::*;
use std::rc::Rc;
@ -25,6 +25,7 @@ pub enum AudioUser {
Popup,
TrayIcon,
Hotkeys,
PrefsWindow,
}
@ -104,6 +105,7 @@ impl Audio {
&self,
card_name: Option<String>,
elem_name: Option<String>,
user: AudioUser,
) -> Result<()> {
debug!("Switching cards");
debug!(
@ -127,8 +129,14 @@ impl Audio {
"Old chan name: {}",
self.acard.borrow().chan_name().unwrap()
);
invoke_handlers(
&self.handlers.borrow(),
AudioSignal::CardInitialized,
user,
);
return Ok(());
// TODO: invoke handler
}

View File

@ -30,7 +30,7 @@ mod errors;
#[macro_use]
mod glade_helpers;
mod alsa_pn;
mod alsa_card;
mod app_state;
mod audio;
mod ui_entry;
@ -38,6 +38,8 @@ mod ui_popup_menu;
mod ui_popup_window;
mod ui_prefs_dialog;
mod ui_tray_icon;
mod support_ui;
mod support_alsa;
use app_state::*;

106
src/support_alsa.rs Normal file
View File

@ -0,0 +1,106 @@
use alsa::card::Card;
use alsa::mixer::{Mixer, Selem, Elem};
use alsa;
use errors::*;
use libc::c_int;
use std::iter::Map;
pub fn get_default_alsa_card() -> Card {
return get_alsa_card_by_id(0);
}
pub fn get_alsa_card_by_id(index: c_int) -> Card {
return Card::new(index);
}
pub fn get_alsa_cards() -> alsa::card::Iter {
return alsa::card::Iter::new();
}
pub fn get_alsa_card_names() -> Vec<String> {
let mut vec = vec![];
for card in get_alsa_cards() {
match card.and_then(|c| c.get_name()) {
Ok(name) => vec.push(name),
_ => (),
}
}
return vec;
}
pub fn get_alsa_card_by_name(name: String) -> Result<Card> {
for r_card in get_alsa_cards() {
let card = r_card?;
let card_name = card.get_name()?;
if name == card_name {
return Ok(card);
}
}
bail!("Not found a matching card named {}", name);
}
pub fn get_mixer(card: &Card) -> Result<Mixer> {
return Mixer::new(&format!("hw:{}", card.get_index()), false).from_err();
}
pub fn get_selem(elem: Elem) -> Selem {
/* in the ALSA API, there are currently only simple elements,
* so this unwrap() should be safe.
*http://www.alsa-project.org/alsa-doc/alsa-lib/group___mixer.html#enum-members */
return Selem::new(elem).unwrap();
}
pub fn get_selems(mixer: &Mixer) -> Map<alsa::mixer::Iter, fn(Elem) -> Selem> {
return mixer.iter().map(get_selem);
}
pub fn get_selem_names(mixer: &Mixer) -> Vec<String> {
let mut vec = vec![];
for selem in get_selems(mixer) {
let n = selem.get_id().get_name().map(|y| String::from(y));
match n {
Ok(name) => vec.push(name),
_ => (),
}
}
return vec;
}
pub fn get_selem_by_name(mixer: &Mixer, name: String) -> Result<Selem> {
for selem in get_selems(mixer) {
let n = selem.get_id().get_name().map(|y| String::from(y))?;
if n == name {
return Ok(selem);
}
}
bail!("Not found a matching selem named {}", name);
}
pub fn vol_to_percent(vol: i64, range: (i64, i64)) -> f64 {
let (min, max) = range;
return ((vol - min) as f64) / ((max - min) as f64) * 100.0;
}
pub fn percent_to_vol(vol: f64, range: (i64, i64)) -> i64 {
let (min, max) = range;
let _v = vol / 100.0 * ((max - min) as f64) + (min as f64);
/* TODO: precision? Use direction. */
return _v as i64;
}

63
src/support_ui.rs Normal file
View File

@ -0,0 +1,63 @@
use errors::*;
use gdk_pixbuf;
use gdk_pixbuf_sys;
use glib::translate::FromGlibPtrFull;
use glib::translate::ToGlibPtr;
use gtk::prelude::*;
use gtk;
use std::path::*;
pub fn copy_pixbuf(pixbuf: &gdk_pixbuf::Pixbuf) -> gdk_pixbuf::Pixbuf {
let new_pixbuf = unsafe {
let gdk_pixbuf = pixbuf.to_glib_full();
let copy = gdk_pixbuf_sys::gdk_pixbuf_copy(gdk_pixbuf);
FromGlibPtrFull::from_glib_full(copy)
};
return new_pixbuf;
}
pub fn pixbuf_new_from_theme(
icon_name: &str,
size: i32,
theme: &gtk::IconTheme,
) -> Result<gdk_pixbuf::Pixbuf> {
let icon_info = theme
.lookup_icon(icon_name, size, gtk::IconLookupFlags::empty())
.ok_or(format!("Couldn't find icon {}", icon_name))?;
debug!(
"Loading stock icon {} from {:?}",
icon_name,
icon_info.get_filename().unwrap_or(PathBuf::new())
);
// TODO: propagate error
let pixbuf = icon_info.load_icon().unwrap();
return Ok(pixbuf);
}
pub fn pixbuf_new_from_file(filename: &str) -> Result<gdk_pixbuf::Pixbuf> {
ensure!(!filename.is_empty(), "Filename is empty");
let s = format!("./data/pixmaps/{}", filename);
let path = Path::new(s.as_str());
if path.exists() {
let str_path = path.to_str().ok_or("Path is not valid unicode")?;
// TODO: propagate error
return Ok(gdk_pixbuf::Pixbuf::new_from_file(str_path).unwrap());
} else {
bail!("Uh-oh");
}
}

View File

@ -1,8 +1,10 @@
use app_state::*;
use audio::AudioUser;
use gtk::prelude::*;
use std::rc::Rc;
use gtk;
use alsa_pn;
use std::rc::Rc;
use support_alsa::*;
create_builder_item!(
@ -13,8 +15,6 @@ create_builder_item!(
);
pub fn show_prefs_dialog(appstate: Rc<AppS>) {
let builder_prefs_dialog = gtk::Builder::new_from_string(
include_str!("../data/ui/prefs-dialog.glade"),
@ -50,6 +50,7 @@ pub fn init_prefs_dialog(appstate: &Rc<AppS>, prefs_dialog: &Rc<PrefsDialog>) {
let card_combo = &prefs_dialog.card_combo;
let pd = prefs_dialog.clone();
// TODO: refill channel combo
card_combo.connect_changed(
move |_| { on_card_combo_changed(&apps, &pd); },
);
@ -76,7 +77,7 @@ fn on_prefs_dialog_show(appstate: &AppS, prefs_dialog: &PrefsDialog) {
/* set card combo */
let cur_card_name =
try_w!(acard.card_name(), "Can't get current card name!");
let available_card_names = alsa_pn::get_alsa_card_names();
let available_card_names = get_alsa_card_names();
/* set_active_id doesn't work, so save the index */
let mut c_index: i32 = -1;
@ -95,7 +96,7 @@ fn on_prefs_dialog_show(appstate: &AppS, prefs_dialog: &PrefsDialog) {
/* set chan combo */
let cur_chan_name = try_w!(acard.chan_name());
let available_chan_names = alsa_pn::get_selem_names(&acard.mixer);
let available_chan_names = get_selem_names(&acard.mixer);
/* set_active_id doesn't work, so save the index */
let mut c_index: i32 = -1;
@ -129,6 +130,7 @@ fn on_card_combo_changed(appstate: &AppS, prefs_dialog: &PrefsDialog) {
appstate.audio.switch_acard(
Some(cur_card_name),
active_chan_item,
AudioUser::PrefsWindow
);
}
}
@ -153,6 +155,7 @@ fn on_chan_combo_changed(appstate: &AppS, prefs_dialog: &PrefsDialog) {
appstate.audio.switch_acard(
cur_card_name,
Some(active_chan_item),
AudioUser::PrefsWindow
);
}
}

View File

@ -1,38 +1,66 @@
use app_state::*;
use gdk;
use gdk_pixbuf;
use gdk_pixbuf_sys;
use gdk_pixbuf_sys::GDK_COLORSPACE_RGB;
use gtk;
use gtk::prelude::*;
use std::rc::Rc;
use std::cell::Cell;
use std::cell::RefCell;
use audio::*;
use errors::*;
use std::path::*;
use glib::translate::ToGlibPtr;
use glib::translate::FromGlibPtrFull;
use gdk;
use gdk_pixbuf;
use gdk_pixbuf_sys::GDK_COLORSPACE_RGB;
use gtk::prelude::*;
use gtk;
use std::cell::Cell;
use std::cell::RefCell;
use std::rc::Rc;
use support_ui::*;
// TODO: on_apply
const ICON_MIN_SIZE: i64 = 16;
const ICON_MIN_SIZE: i32 = 16;
fn copy_pixbuf(pixbuf: &gdk_pixbuf::Pixbuf) -> gdk_pixbuf::Pixbuf {
let new_pixbuf = unsafe {
let gdk_pixbuf = pixbuf.to_glib_full();
let copy = gdk_pixbuf_sys::gdk_pixbuf_copy(gdk_pixbuf);
FromGlibPtrFull::from_glib_full(copy)
};
return new_pixbuf;
pub struct TrayIcon {
pub volmeter: VolMeter,
pub audio_pix: AudioPix,
pub status_icon: gtk::StatusIcon,
pub icon_size: Cell<i64>,
}
struct VolMeter {
impl TrayIcon {
// TODO: take settings as parameter
pub fn new() -> Result<TrayIcon> {
let volmeter = VolMeter::new();
let audio_pix = AudioPix::new_from_pnmixer()?;
let status_icon = gtk::StatusIcon::new();
return Ok(TrayIcon { volmeter, audio_pix, status_icon, icon_size: Cell::new(ICON_MIN_SIZE) });
}
fn update(&self, audio: &Audio, m_size: Option<i64>) {
match m_size {
Some(s) => {
if s < ICON_MIN_SIZE {
self.icon_size.set(ICON_MIN_SIZE);
} else {
self.icon_size.set(s);
}
},
None => (),
}
let cur_vol = try_w!(audio.vol());
let pixbuf = self.audio_pix.select_pix(audio.vol_level());
let vol_pix = try_w!(self.volmeter.meter_draw(cur_vol as i64,
&pixbuf));
self.status_icon.set_from_pixbuf(Some(&vol_pix));
}
}
pub struct VolMeter {
pub red: u8,
pub green: u8,
pub blue: u8,
@ -153,7 +181,7 @@ impl VolMeter {
#[derive(Clone, Debug)]
struct AudioPix {
pub struct AudioPix {
muted: gdk_pixbuf::Pixbuf,
low: gdk_pixbuf::Pixbuf,
medium: gdk_pixbuf::Pixbuf,
@ -213,71 +241,20 @@ impl AudioPix {
}
fn pixbuf_new_from_theme(
icon_name: &str,
size: i32,
theme: &gtk::IconTheme,
) -> Result<gdk_pixbuf::Pixbuf> {
let icon_info = theme
.lookup_icon(icon_name, size, gtk::IconLookupFlags::empty())
.ok_or(format!("Couldn't find icon {}", icon_name))?;
debug!(
"Loading stock icon {} from {:?}",
icon_name,
icon_info.get_filename().unwrap_or(PathBuf::new())
);
// TODO: propagate error
let pixbuf = icon_info.load_icon().unwrap();
return Ok(pixbuf);
}
fn pixbuf_new_from_file(filename: &str) -> Result<gdk_pixbuf::Pixbuf> {
ensure!(!filename.is_empty(), "Filename is empty");
let s = format!("./data/pixmaps/{}", filename);
let path = Path::new(s.as_str());
if path.exists() {
let str_path = path.to_str().ok_or("Path is not valid unicode")?;
// TODO: propagate error
return Ok(gdk_pixbuf::Pixbuf::new_from_file(str_path).unwrap());
} else {
bail!("Uh-oh");
}
}
fn update_tray_icon(audio_pix: &AudioPix, appstate: &AppS) {
let cur_vol = try_w!(appstate.audio.vol());
let status_icon = &appstate.gui.status_icon;
let pixbuf = audio_pix.select_pix(appstate.audio.vol_level());
let volmeter = VolMeter::new();
let vol_pix = try_w!(volmeter.meter_draw(cur_vol as i64, &pixbuf));
status_icon.set_from_pixbuf(Some(&vol_pix));
}
pub fn init_tray_icon(appstate: Rc<AppS>) {
let audio_pix = Rc::new(RefCell::new(try_w!(AudioPix::new_from_pnmixer())));
update_tray_icon(&audio_pix.borrow(), &appstate);
let audio = &appstate.audio;
let tray_icon = &appstate.gui.tray_icon;
tray_icon.update(&audio, None);
tray_icon.status_icon.set_visible(true);
/* connect audio handler */
{
let _audio_pix = audio_pix.clone();
let apps = appstate.clone();
appstate.audio.connect_handler(
Box::new(move |s, u| match (s, u) {
(AudioSignal::ValuesChanged, _) => {
update_tray_icon(&_audio_pix.borrow(), &apps);
apps.gui.tray_icon.update(&apps.audio, None);
}
_ => (),
}),
@ -287,27 +264,22 @@ pub fn init_tray_icon(appstate: Rc<AppS>) {
/* tray_icon.connect_size_changed */
{
let apps = appstate.clone();
let tray_icon = &appstate.gui.status_icon;
let _audio_pix = audio_pix.clone();
tray_icon.connect_size_changed(move |_, size| {
on_tray_icon_size_changed(&apps, _audio_pix.as_ref(), size)
tray_icon.status_icon.connect_size_changed(move |_, size| {
apps.gui.tray_icon.update(&apps.audio, Some(size as i64));
return false;
});
tray_icon.set_visible(true);
}
/* tray_icon.connect_activate */
{
let apps = appstate.clone();
let tray_icon = &appstate.gui.status_icon;
tray_icon.connect_activate(move |_| on_tray_icon_activate(&apps));
tray_icon.set_visible(true);
tray_icon.status_icon.connect_activate(move |_| on_tray_icon_activate(&apps));
}
/* tray_icon.connect_scroll_event */
{
let apps = appstate.clone();
let tray_icon = &appstate.clone().gui.status_icon;
tray_icon.connect_scroll_event(
tray_icon.status_icon.connect_scroll_event(
move |_, e| on_tray_icon_scroll_event(&apps, &e),
);
}
@ -315,8 +287,7 @@ pub fn init_tray_icon(appstate: Rc<AppS>) {
/* tray_icon.connect_popup_menu */
{
let apps = appstate.clone();
let tray_icon = &appstate.clone().gui.status_icon;
tray_icon.connect_popup_menu(
tray_icon.status_icon.connect_popup_menu(
move |_, _, _| on_tray_icon_popup_menu(&apps),
);
}
@ -324,8 +295,7 @@ pub fn init_tray_icon(appstate: Rc<AppS>) {
/* tray_icon.connect_button_release_event */
{
let apps = appstate.clone();
let tray_icon = &appstate.clone().gui.status_icon;
tray_icon.connect_button_release_event(
tray_icon.status_icon.connect_button_release_event(
move |_, eb| on_tray_button_release_event(&apps, eb),
);
}
@ -374,30 +344,6 @@ fn on_tray_icon_scroll_event(
}
fn on_tray_icon_size_changed(
appstate: &AppS,
audio_pix: &RefCell<AudioPix>,
size: i32,
) -> bool {
debug!("Tray icon size is now {}", size);
let mut size = size;
if size < ICON_MIN_SIZE {
size = ICON_MIN_SIZE;
debug!("Forcing size to the minimum value {}", size);
}
{
let mut pix = audio_pix.borrow_mut();
*pix = try_wr!(AudioPix::new_from_pnmixer(), false);
}
update_tray_icon(&audio_pix.borrow(), &appstate);
return false;
}
fn on_tray_button_release_event(
appstate: &AppS,
event_button: &gdk::EventButton,