Update
This commit is contained in:
parent
64367bb187
commit
8907a2005c
@ -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"><b>Sound Device</b></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"><b>Sound Device</b></property>
|
||||
<property name="label" translatable="yes"><b>Icon Theme</b></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>
|
||||
|
@ -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;
|
||||
}
|
@ -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),
|
||||
};
|
||||
|
14
src/audio.rs
14
src/audio.rs
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
106
src/support_alsa.rs
Normal 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
63
src/support_ui.rs
Normal 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: >k::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");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -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: >k::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,
|
||||
|
Loading…
Reference in New Issue
Block a user