use GtkBuilder to load UI from XML-file instead of creating it via code
This commit is contained in:
parent
c8f51ad801
commit
1b2b8dcc75
2 changed files with 1028 additions and 369 deletions
773
data/gtk.glade
Normal file
773
data/gtk.glade
Normal file
|
|
@ -0,0 +1,773 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.20.0 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.20"/>
|
||||
<object class="GtkAdjustment" id="library-scale-adjustment">
|
||||
<property name="lower">100</property>
|
||||
<property name="upper">1000</property>
|
||||
<property name="value">150</property>
|
||||
<property name="step_increment">1</property>
|
||||
<property name="page_increment">10</property>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="server-port-adjustment">
|
||||
<property name="lower">1024</property>
|
||||
<property name="upper">9999</property>
|
||||
<property name="value">6600</property>
|
||||
<property name="step_increment">1</property>
|
||||
<property name="page_increment">100</property>
|
||||
</object>
|
||||
<object class="GtkApplicationWindow" id="appwindow">
|
||||
<property name="can_focus">False</property>
|
||||
<signal name="destroy" handler="on_appwindow_destroy" swapped="no"/>
|
||||
<signal name="size-allocate" handler="on_appwindow_size_allocate" swapped="no"/>
|
||||
<signal name="window-state-event" handler="on_appwindow_window_state_event" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkRevealer" id="server-info-revealer">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkInfoBar" id="server-info-bar">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_start">10</property>
|
||||
<property name="margin_end">10</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="show_close_button">True</property>
|
||||
<signal name="close" handler="on_server-info-bar_close" swapped="no"/>
|
||||
<signal name="response" handler="on_server-info-bar_response" swapped="no"/>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkButtonBox">
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child internal-child="content_area">
|
||||
<object class="GtkBox">
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="server-info-label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStack" id="panelstack">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="server-panel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkGrid">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="column_spacing">5</property>
|
||||
<property name="row_homogeneous">True</property>
|
||||
<property name="column_homogeneous">True</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="server-zeroconf-list">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<signal name="focus-out-event" handler="on_server-zeroconf-list_focus_out_event" swapped="no"/>
|
||||
<child internal-child="selection">
|
||||
<object class="GtkTreeSelection" id="server-zeroconf-list-selection">
|
||||
<signal name="changed" handler="on_server-zeroconf-list-selection_changed" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">5</property>
|
||||
<property name="orientation">vertical</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
<property name="height">8</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="server-host">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="text" translatable="yes">localhost</property>
|
||||
<property name="placeholder_text" translatable="yes">Host</property>
|
||||
<signal name="focus-out-event" handler="on_server-host_focus_out_event" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="server-image-dir">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="placeholder_text" translatable="yes">Image Directory</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">7</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="server-password">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="visibility">False</property>
|
||||
<property name="placeholder_text" translatable="yes">Password</property>
|
||||
<property name="input_purpose">password</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="server-port">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="adjustment">server-port-adjustment</property>
|
||||
<property name="value">6600</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label" translatable="yes">Host:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label" translatable="yes">Port:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label" translatable="yes">Password:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label" translatable="yes">Image Dir:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">6</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">connection</property>
|
||||
<property name="title" translatable="yes">Server</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="cover-panel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="cover-scroll">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="window_placement_set">False</property>
|
||||
<property name="kinetic_scrolling">False</property>
|
||||
<property name="overlay_scrolling">False</property>
|
||||
<child>
|
||||
<object class="GtkViewport">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkEventBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="cover-image">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-missing-image</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="padding">10</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScale" id="cover-songs">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="round_digits">1</property>
|
||||
<property name="draw_value">False</property>
|
||||
<signal name="button-press-event" handler="on_cover-songs_button_press_event" swapped="no"/>
|
||||
<signal name="button-release-event" handler="on_cover-songs_button_release_event" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="padding">10</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="padding">10</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkGrid">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_top">5</property>
|
||||
<property name="margin_bottom">5</property>
|
||||
<property name="row_spacing">5</property>
|
||||
<property name="row_homogeneous">True</property>
|
||||
<property name="column_homogeneous">True</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="cover-album">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Album</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="cover-date">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Date</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="cover-artist">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Artist</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="padding">10</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">cover</property>
|
||||
<property name="title" translatable="yes">Cover</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="playlist-panel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkToolbar">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="show_arrow">False</property>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="playlist-clear">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="icon_name">edit-clear</property>
|
||||
<signal name="clicked" handler="on_playlist-clear_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<style>
|
||||
<class name="no-bg"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<child>
|
||||
<object class="GtkIconView" id="playlist-iconview">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="margin">0</property>
|
||||
<property name="item_orientation">horizontal</property>
|
||||
<property name="columns">3</property>
|
||||
<property name="row_spacing">0</property>
|
||||
<property name="column_spacing">0</property>
|
||||
<property name="tooltip_column">1</property>
|
||||
<property name="item_padding">5</property>
|
||||
<style>
|
||||
<class name="no-bg"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<style>
|
||||
<class name="no-bg"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">playlist</property>
|
||||
<property name="title" translatable="yes">Playlist</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="library-panel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkRevealer" id="library-progress-revealer">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="transition_type">none</property>
|
||||
<child>
|
||||
<object class="GtkProgressBar" id="library-progress">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="fraction">0.5</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkHeaderBar">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="spacing">0</property>
|
||||
<child>
|
||||
<object class="GtkToolbar">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="library-update">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="icon_name">view-refresh</property>
|
||||
<signal name="clicked" handler="on_library-update_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<style>
|
||||
<class name="no-bg"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child type="title">
|
||||
<object class="GtkSearchEntry" id="library-filter">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="primary_icon_name">edit-find-symbolic</property>
|
||||
<property name="primary_icon_activatable">False</property>
|
||||
<property name="primary_icon_sensitive">False</property>
|
||||
<property name="placeholder_text" translatable="yes">search library</property>
|
||||
<signal name="search-changed" handler="on_library-filter_search_changed" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolbar">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkToolItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkScale" id="library-grid-scale">
|
||||
<property name="width_request">100</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="adjustment">library-scale-adjustment</property>
|
||||
<property name="lower_stepper_sensitivity">off</property>
|
||||
<property name="upper_stepper_sensitivity">off</property>
|
||||
<property name="restrict_to_fill_level">False</property>
|
||||
<property name="fill_level">0</property>
|
||||
<property name="digits">0</property>
|
||||
<property name="draw_value">False</property>
|
||||
<signal name="button-release-event" handler="on_library-grid-scale_button_release_event" swapped="no"/>
|
||||
<signal name="change-value" handler="on_library-grid-scale_change_value" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkComboBox" id="library-sort">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<signal name="changed" handler="on_library-sort_changed" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToggleToolButton" id="library-sort-order">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="icon_name">view-sort-descending</property>
|
||||
<property name="active">True</property>
|
||||
<signal name="clicked" handler="on_library-sort-order_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<style>
|
||||
<class name="no-bg"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<style>
|
||||
<class name="no-bg"/>
|
||||
<class name="no-border"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<child>
|
||||
<object class="GtkIconView" id="library-iconview">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="margin">0</property>
|
||||
<property name="item_orientation">horizontal</property>
|
||||
<property name="row_spacing">0</property>
|
||||
<property name="column_spacing">0</property>
|
||||
<property name="tooltip_column">1</property>
|
||||
<property name="item_padding">5</property>
|
||||
<signal name="item-activated" handler="on_library-iconview_item_activated" swapped="no"/>
|
||||
<style>
|
||||
<class name="no-bg"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<style>
|
||||
<class name="no-bg"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">library</property>
|
||||
<property name="title" translatable="yes">Library</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="headerbar">
|
||||
<property name="name">headerbar</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="show_close_button">True</property>
|
||||
<child>
|
||||
<object class="GtkToolbar">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="show_arrow">False</property>
|
||||
<child>
|
||||
<object class="GtkToggleToolButton" id="headerbar-connect">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="icon_name">gtk-disconnect</property>
|
||||
<signal name="toggled" handler="on_headerbar-connect_toggled" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorToolItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToggleToolButton" id="headerbar-playpause">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="icon_name">media-playback-start</property>
|
||||
<signal name="toggled" handler="on_headerbar-playpause_toggled" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<style>
|
||||
<class name="no-bg"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child type="title">
|
||||
<object class="GtkStackSwitcher" id="header-panelswitcher">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stack">panelstack</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolbar">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="show_arrow">False</property>
|
||||
<child>
|
||||
<object class="GtkToolItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkVolumeButton" id="headerbar-volume">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="focus_on_click">False</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="relief">none</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="icons">audio-volume-muted-symbolic
|
||||
audio-volume-high-symbolic
|
||||
audio-volume-low-symbolic
|
||||
audio-volume-medium-symbolic</property>
|
||||
<signal name="button-press-event" handler="on_headerbar-volume_button_press_event" swapped="no"/>
|
||||
<signal name="button-release-event" handler="on_headerbar-volume_button_release_event" swapped="no"/>
|
||||
<signal name="value-changed" handler="on_headerbar-volume_value_changed" swapped="no"/>
|
||||
<child internal-child="plus_button">
|
||||
<object class="GtkButton">
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="relief">none</property>
|
||||
</object>
|
||||
</child>
|
||||
<child internal-child="minus_button">
|
||||
<object class="GtkButton">
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="relief">none</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<style>
|
||||
<class name="no-bg"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<style>
|
||||
<class name="bg-texture"/>
|
||||
</style>
|
||||
</object>
|
||||
</interface>
|
||||
628
mcg/mcgGtk.py
628
mcg/mcgGtk.py
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
"""MPDCoverGrid is a client for the Music Player Daemon, focused on albums instead of single tracks."""
|
||||
|
||||
__version__ = "0.4"
|
||||
__version__ = "0.5"
|
||||
|
||||
|
||||
import gi
|
||||
|
|
@ -48,20 +48,22 @@ class Application(Gtk.Application):
|
|||
def __init__(self):
|
||||
Gtk.Application.__init__(self, application_id="de.coderkun.mcg", flags=Gio.ApplicationFlags.FLAGS_NONE)
|
||||
self._window = None
|
||||
|
||||
|
||||
def do_startup(self):
|
||||
Gtk.Application.do_startup(self)
|
||||
self._settings = Gio.Settings.new(Application.SETTINGS_BASE_KEY)
|
||||
|
||||
# Signals
|
||||
self.connect('startup', self.on_startup)
|
||||
self.connect('activate', self.on_activate)
|
||||
|
||||
|
||||
def on_startup(self, app):
|
||||
self.load_css()
|
||||
|
||||
# Create builder to load UI
|
||||
self._builder = Gtk.Builder()
|
||||
self._builder.add_from_file('data/gtk.glade')
|
||||
|
||||
def on_activate(self, app):
|
||||
|
||||
def do_activate(self):
|
||||
Gtk.Application.do_activate(self)
|
||||
if not self._window:
|
||||
self._window = Window(self, Application.TITLE, self._settings)
|
||||
self._window = Window(self, self._builder, Application.TITLE, self._settings)
|
||||
self._window.present()
|
||||
|
||||
|
||||
|
|
@ -111,18 +113,17 @@ class Application(Gtk.Application):
|
|||
|
||||
|
||||
|
||||
class Window(Gtk.ApplicationWindow):
|
||||
STYLE_CLASS_BG_TEXTURE = 'bg-texture'
|
||||
STYLE_CLASS_NO_BG = 'no-bg'
|
||||
STYLE_CLASS_NO_BORDER = 'no-border'
|
||||
class Window():
|
||||
_PANEL_INDEX_CONNECTION = 0
|
||||
_PANEL_INDEX_COVER = 1
|
||||
_PANEL_INDEX_PLAYLIST = 2
|
||||
_PANEL_INDEX_LIBRARY = 3
|
||||
|
||||
|
||||
def __init__(self, app, title, settings):
|
||||
Gtk.ApplicationWindow.__init__(self, title=title, application=app)
|
||||
def __init__(self, app, builder, title, settings):
|
||||
self._appwindow = builder.get_object('appwindow')
|
||||
self._appwindow.set_application(app)
|
||||
self._appwindow.set_title(title)
|
||||
self._settings = settings
|
||||
self._panels = []
|
||||
self._mcg = mcg.Client()
|
||||
|
|
@ -138,31 +139,21 @@ class Window(Gtk.ApplicationWindow):
|
|||
self._fullscreened = False
|
||||
|
||||
# Panels
|
||||
self._panels.append(ConnectionPanel())
|
||||
self._panels.append(CoverPanel())
|
||||
self._panels.append(PlaylistPanel())
|
||||
self._panels.append(LibraryPanel())
|
||||
self._panels.append(ConnectionPanel(builder))
|
||||
self._panels.append(CoverPanel(builder))
|
||||
self._panels.append(PlaylistPanel(builder))
|
||||
self._panels.append(LibraryPanel(builder))
|
||||
|
||||
# Widgets
|
||||
self._main_box = Gtk.VBox()
|
||||
self._main_box.get_style_context().add_class(Window.STYLE_CLASS_NO_BG)
|
||||
self.add(self._main_box)
|
||||
# InfoBar
|
||||
self._infobar = InfoBar()
|
||||
self._main_box.pack_start(self._infobar, False, True, 0)
|
||||
self._infobar = InfoBar(builder)
|
||||
# Stack
|
||||
self._stack = Gtk.Stack()
|
||||
for panel in self._panels:
|
||||
self._stack.add_titled(panel, panel.get_name(), panel.get_title())
|
||||
self._stack.set_homogeneous(True)
|
||||
self._main_box.pack_end(self._stack, True, True, 0)
|
||||
self._stack = builder.get_object('panelstack')
|
||||
# Header
|
||||
self._header_bar = HeaderBar(self._stack)
|
||||
self.set_titlebar(self._header_bar)
|
||||
self._header_bar = HeaderBar(builder)
|
||||
|
||||
# Properties
|
||||
self._header_bar.set_sensitive(False, False)
|
||||
self.get_style_context().add_class(Window.STYLE_CLASS_BG_TEXTURE)
|
||||
self._panels[Window._PANEL_INDEX_CONNECTION].set_host(self._settings.get_string(Application.SETTING_HOST))
|
||||
self._panels[Window._PANEL_INDEX_CONNECTION].set_port(self._settings.get_int(Application.SETTING_PORT))
|
||||
if use_keyring:
|
||||
|
|
@ -174,17 +165,14 @@ class Window(Gtk.ApplicationWindow):
|
|||
self._panels[Window._PANEL_INDEX_LIBRARY].set_sort_type(self._settings.get_boolean(Application.SETTING_SORT_TYPE))
|
||||
|
||||
# Signals
|
||||
self.connect('size-allocate', self.on_resize)
|
||||
self.connect('window-state-event', self.on_state)
|
||||
self.connect('destroy', self.on_destroy)
|
||||
self._header_bar.connect_signal(HeaderBar.SIGNAL_STACK_SWITCHED, self.on_header_bar_stack_switched)
|
||||
self._header_bar.connect_signal(HeaderBar.SIGNAL_CONNECT, self.on_header_bar_connect)
|
||||
self._header_bar.connect_signal(HeaderBar.SIGNAL_PLAYPAUSE, self.on_header_bar_playpause)
|
||||
self._header_bar.connect_signal(HeaderBar.SIGNAL_SET_VOLUME, self.on_header_bar_set_volume)
|
||||
self._panels[Window._PANEL_INDEX_CONNECTION].connect_signal(ConnectionPanel.SIGNAL_CONNECTION_CHANGED, self.on_connection_panel_connection_changed)
|
||||
self._panels[Window._PANEL_INDEX_PLAYLIST].connect_signal(PlaylistPanel.SIGNAL_CLEAR_PLAYLIST, self.on_playlist_panel_clear_playlist)
|
||||
self._panels[Window._PANEL_INDEX_COVER].connect_signal(CoverPanel.SIGNAL_TOGGLE_FULLSCREEN, self.on_cover_panel_toggle_fullscreen)
|
||||
self._panels[Window._PANEL_INDEX_COVER].connect_signal(CoverPanel.SIGNAL_SET_SONG, self.on_cover_panel_set_song)
|
||||
self._panels[Window._PANEL_INDEX_PLAYLIST].connect_signal(PlaylistPanel.SIGNAL_CLEAR_PLAYLIST, self.on_playlist_panel_clear_playlist)
|
||||
self._panels[Window._PANEL_INDEX_LIBRARY].connect_signal(LibraryPanel.SIGNAL_UPDATE, self.on_library_panel_update)
|
||||
self._panels[Window._PANEL_INDEX_LIBRARY].connect_signal(LibraryPanel.SIGNAL_PLAY, self.on_library_panel_play)
|
||||
self._panels[Window._PANEL_INDEX_LIBRARY].connect_signal(LibraryPanel.SIGNAL_ITEM_SIZE_CHANGED, self.on_library_panel_item_size_changed)
|
||||
|
|
@ -199,21 +187,37 @@ class Window(Gtk.ApplicationWindow):
|
|||
self._settings.connect('changed::'+Application.SETTING_ITEM_SIZE, self.on_settings_item_size_changed)
|
||||
self._settings.connect('changed::'+Application.SETTING_SORT_ORDER, self.on_settings_sort_order_changed)
|
||||
self._settings.connect('changed::'+Application.SETTING_SORT_TYPE, self.on_settings_sort_type_changed)
|
||||
handlers = {
|
||||
'on_appwindow_size_allocate': self.on_resize,
|
||||
'on_appwindow_window_state_event': self.on_state,
|
||||
'on_appwindow_destroy': self.on_destroy
|
||||
}
|
||||
handlers.update(self._header_bar.get_signal_handlers())
|
||||
handlers.update(self._infobar.get_signal_handlers())
|
||||
handlers.update(self._panels[Window._PANEL_INDEX_CONNECTION].get_signal_handlers())
|
||||
handlers.update(self._panels[Window._PANEL_INDEX_COVER].get_signal_handlers())
|
||||
handlers.update(self._panels[Window._PANEL_INDEX_PLAYLIST].get_signal_handlers())
|
||||
handlers.update(self._panels[Window._PANEL_INDEX_LIBRARY].get_signal_handlers())
|
||||
builder.connect_signals(handlers)
|
||||
|
||||
# Actions
|
||||
self.resize(int(self._size[0]), int(self._size[1]))
|
||||
self._appwindow.resize(int(self._size[0]), int(self._size[1]))
|
||||
if self._maximized:
|
||||
self.maximize()
|
||||
self.show_all()
|
||||
self._infobar.hide()
|
||||
self._stack.set_visible_child(self._panels[Window._PANEL_INDEX_CONNECTION])
|
||||
self._appwindow.maximize()
|
||||
self._appwindow.show_all()
|
||||
self._stack.set_visible_child(self._panels[Window._PANEL_INDEX_CONNECTION].get())
|
||||
if self._settings.get_boolean(Application.SETTING_CONNECTED):
|
||||
self._connect()
|
||||
|
||||
|
||||
def present(self):
|
||||
self._appwindow.present()
|
||||
self._appwindow.resize(800, 600)
|
||||
|
||||
|
||||
def on_resize(self, widget, event):
|
||||
if not self._maximized:
|
||||
self._size = (self.get_allocation().width, self.get_allocation().height)
|
||||
self._size = (self._appwindow.get_allocation().width, self._appwindow.get_allocation().height)
|
||||
|
||||
|
||||
def on_state(self, widget, state):
|
||||
|
|
@ -343,7 +347,7 @@ class Window(Gtk.ApplicationWindow):
|
|||
|
||||
def on_settings_panel_changed(self, settings, key):
|
||||
panel_index = settings.get_int(key)
|
||||
self._stack.set_visible_child(self._panels[panel_index])
|
||||
self._stack.set_visible_child(self._panels[panel_index].get())
|
||||
|
||||
|
||||
def on_settings_item_size_changed(self, settings, key):
|
||||
|
|
@ -366,7 +370,7 @@ class Window(Gtk.ApplicationWindow):
|
|||
|
||||
def _connect(self):
|
||||
connection_panel = self._panels[Window._PANEL_INDEX_CONNECTION]
|
||||
connection_panel.set_sensitive(False)
|
||||
connection_panel.get().set_sensitive(False)
|
||||
self._header_bar.set_sensitive(False, True)
|
||||
if self._mcg.is_connected():
|
||||
self._mcg.disconnect()
|
||||
|
|
@ -383,7 +387,7 @@ class Window(Gtk.ApplicationWindow):
|
|||
def _connect_connected(self):
|
||||
self._header_bar.connected()
|
||||
self._header_bar.set_sensitive(True, False)
|
||||
self._stack.set_visible_child(self._panels[self._settings.get_int(Application.SETTING_PANEL)])
|
||||
self._stack.set_visible_child(self._panels[self._settings.get_int(Application.SETTING_PANEL)].get())
|
||||
|
||||
|
||||
def _connect_disconnected(self):
|
||||
|
|
@ -392,8 +396,8 @@ class Window(Gtk.ApplicationWindow):
|
|||
self._header_bar.disconnected()
|
||||
self._header_bar.set_sensitive(False, False)
|
||||
self._save_visible_panel()
|
||||
self._stack.set_visible_child(self._panels[Window._PANEL_INDEX_CONNECTION])
|
||||
self._panels[Window._PANEL_INDEX_CONNECTION].set_sensitive(True)
|
||||
self._stack.set_visible_child(self._panels[Window._PANEL_INDEX_CONNECTION].get())
|
||||
self._panels[Window._PANEL_INDEX_CONNECTION].get().set_sensitive(True)
|
||||
|
||||
|
||||
def _fullscreen(self, fullscreened_new):
|
||||
|
|
@ -408,81 +412,62 @@ class Window(Gtk.ApplicationWindow):
|
|||
|
||||
|
||||
def _save_visible_panel(self):
|
||||
panel_index_selected = self._panels.index(self._stack.get_visible_child())
|
||||
if(panel_index_selected > 0):
|
||||
panels = [panel.get() for panel in self._panels]
|
||||
panel_index_selected = panels.index(self._stack.get_visible_child())
|
||||
if panel_index_selected > 0:
|
||||
self._settings.set_int(Application.SETTING_PANEL, panel_index_selected)
|
||||
|
||||
|
||||
def _show_error(self, message):
|
||||
self._infobar.show_error(message)
|
||||
self._infobar.show()
|
||||
|
||||
|
||||
|
||||
|
||||
class HeaderBar(mcg.Base, Gtk.HeaderBar):
|
||||
class HeaderBar(mcg.Base):
|
||||
SIGNAL_STACK_SWITCHED = 'stack-switched'
|
||||
SIGNAL_CONNECT = 'connect'
|
||||
SIGNAL_PLAYPAUSE = 'playpause'
|
||||
SIGNAL_CONNECT = 'on_headerbar-connect_toggled'
|
||||
SIGNAL_PLAYPAUSE = 'on_headerbar-playpause_toggled'
|
||||
SIGNAL_SET_VOLUME = 'set-volume'
|
||||
|
||||
|
||||
def __init__(self, stack):
|
||||
def __init__(self, builder):
|
||||
mcg.Base.__init__(self)
|
||||
Gtk.HeaderBar.__init__(self)
|
||||
self._stack = stack
|
||||
|
||||
self._buttons = {}
|
||||
self._button_handlers = {}
|
||||
self._changing_volume = False
|
||||
self._setting_volume = False
|
||||
|
||||
# Widgets
|
||||
# StackSwitcher
|
||||
self._stack_switcher = StackSwitcher()
|
||||
self._stack_switcher.set_stack(self._stack)
|
||||
self.set_custom_title(self._stack_switcher)
|
||||
# Buttons left
|
||||
self._left_toolbar = Gtk.Toolbar()
|
||||
self._left_toolbar.set_show_arrow(False)
|
||||
self._left_toolbar.get_style_context().add_class(Window.STYLE_CLASS_NO_BG)
|
||||
self.pack_start(self._left_toolbar)
|
||||
# Buttons left: Connection
|
||||
self._buttons[HeaderBar.SIGNAL_CONNECT] = Gtk.ToggleToolButton.new_from_stock(Gtk.STOCK_DISCONNECT)
|
||||
self._left_toolbar.add(self._buttons[HeaderBar.SIGNAL_CONNECT])
|
||||
# Buttons left: Separator
|
||||
self._left_toolbar.add(Gtk.SeparatorToolItem())
|
||||
# Buttons left: Playback
|
||||
self._buttons[HeaderBar.SIGNAL_PLAYPAUSE] = Gtk.ToggleToolButton.new_from_stock(Gtk.STOCK_MEDIA_PLAY)
|
||||
self._buttons[HeaderBar.SIGNAL_PLAYPAUSE].set_sensitive(False)
|
||||
self._left_toolbar.add(self._buttons[HeaderBar.SIGNAL_PLAYPAUSE])
|
||||
# Buttons right
|
||||
self._right_toolbar = Gtk.Toolbar()
|
||||
self._right_toolbar.set_show_arrow(False)
|
||||
self._right_toolbar.get_style_context().add_class(Window.STYLE_CLASS_NO_BG)
|
||||
self.pack_end(self._right_toolbar)
|
||||
# Buttons right: Volume
|
||||
item = Gtk.ToolItem()
|
||||
self._buttons[HeaderBar.SIGNAL_SET_VOLUME] = Gtk.VolumeButton()
|
||||
self._buttons[HeaderBar.SIGNAL_SET_VOLUME].set_sensitive(False)
|
||||
item.add(self._buttons[HeaderBar.SIGNAL_SET_VOLUME])
|
||||
self._right_toolbar.add(item)
|
||||
|
||||
# Properties
|
||||
self.set_show_close_button(True)
|
||||
self._header_bar = builder.get_object('headerbar')
|
||||
self._stack_switcher = StackSwitcher(builder)
|
||||
self._buttons[HeaderBar.SIGNAL_CONNECT] = builder.get_object('headerbar-connect')
|
||||
self._buttons[HeaderBar.SIGNAL_PLAYPAUSE] = builder.get_object('headerbar-playpause')
|
||||
self._buttons[HeaderBar.SIGNAL_SET_VOLUME] = builder.get_object('headerbar-volume')
|
||||
|
||||
# Signals
|
||||
self._stack_switcher.connect_signal(StackSwitcher.SIGNAL_STACK_SWITCHED, self.on_stack_switched)
|
||||
self._button_handlers[HeaderBar.SIGNAL_CONNECT] = self._buttons[HeaderBar.SIGNAL_CONNECT].connect('toggled', self._callback_from_widget, self.SIGNAL_CONNECT)
|
||||
self._button_handlers[HeaderBar.SIGNAL_PLAYPAUSE] = self._buttons[HeaderBar.SIGNAL_PLAYPAUSE].connect('toggled', self._callback_from_widget, self.SIGNAL_PLAYPAUSE)
|
||||
self._buttons[HeaderBar.SIGNAL_SET_VOLUME].connect('value-changed', self.on_volume_changed)
|
||||
self._buttons[HeaderBar.SIGNAL_SET_VOLUME].connect('button-press-event', self.on_volume_set_active, True)
|
||||
self._buttons[HeaderBar.SIGNAL_SET_VOLUME].connect('button-release-event', self.on_volume_set_active, False)
|
||||
self._button_handlers = {
|
||||
'on_headerbar-connect_toggled': self._callback_from_widget,
|
||||
'on_headerbar-playpause_toggled': self._callback_from_widget,
|
||||
'on_headerbar-volume_value_changed': self.on_volume_changed,
|
||||
'on_headerbar-volume_button_press_event': self.on_volume_press,
|
||||
'on_headerbar-volume_button_release_event': self.on_volume_release
|
||||
}
|
||||
|
||||
|
||||
def get(self):
|
||||
return self._header_bar
|
||||
|
||||
|
||||
def get_signal_handlers(self):
|
||||
return self._button_handlers
|
||||
|
||||
|
||||
def set_sensitive(self, sensitive, connecting):
|
||||
for button_signal in self._buttons:
|
||||
self._buttons[button_signal].set_sensitive(sensitive)
|
||||
self._stack_switcher.set_sensitive(sensitive)
|
||||
self._stack_switcher.get().set_sensitive(sensitive)
|
||||
self._buttons[HeaderBar.SIGNAL_CONNECT].set_sensitive(not connecting)
|
||||
|
||||
|
||||
|
|
@ -495,30 +480,58 @@ class HeaderBar(mcg.Base, Gtk.HeaderBar):
|
|||
self._callback(self.SIGNAL_SET_VOLUME, int(value*100))
|
||||
|
||||
|
||||
def on_volume_set_active(self, widget, event, active):
|
||||
def on_volume_press(self, *args):
|
||||
self.volume_set_active(None, None, True)
|
||||
|
||||
|
||||
def on_volume_release(self, *args):
|
||||
self.volume_set_active(None, None, False)
|
||||
|
||||
|
||||
def volume_set_active(self, widget, event, active):
|
||||
self._changing_volume = active
|
||||
|
||||
|
||||
def connected(self):
|
||||
self._buttons[HeaderBar.SIGNAL_CONNECT].handler_block_by_func(
|
||||
self._button_handlers[HeaderBar.SIGNAL_CONNECT]
|
||||
)
|
||||
self._buttons[HeaderBar.SIGNAL_CONNECT].set_stock_id(Gtk.STOCK_CONNECT)
|
||||
with self._buttons[HeaderBar.SIGNAL_CONNECT].handler_block(self._button_handlers[HeaderBar.SIGNAL_CONNECT]):
|
||||
self._buttons[HeaderBar.SIGNAL_CONNECT].set_active(True)
|
||||
self._buttons[HeaderBar.SIGNAL_CONNECT].handler_unblock_by_func(
|
||||
self._button_handlers[HeaderBar.SIGNAL_CONNECT]
|
||||
)
|
||||
|
||||
|
||||
def disconnected(self):
|
||||
self._buttons[HeaderBar.SIGNAL_CONNECT].handler_block_by_func(
|
||||
self._button_handlers[HeaderBar.SIGNAL_CONNECT]
|
||||
)
|
||||
self._buttons[HeaderBar.SIGNAL_CONNECT].set_stock_id(Gtk.STOCK_DISCONNECT)
|
||||
with self._buttons[HeaderBar.SIGNAL_CONNECT].handler_block(self._button_handlers[HeaderBar.SIGNAL_CONNECT]):
|
||||
self._buttons[HeaderBar.SIGNAL_CONNECT].set_active(False)
|
||||
self._buttons[HeaderBar.SIGNAL_CONNECT].handler_unblock_by_func(
|
||||
self._button_handlers[HeaderBar.SIGNAL_CONNECT]
|
||||
)
|
||||
|
||||
|
||||
def set_play(self):
|
||||
with self._buttons[HeaderBar.SIGNAL_PLAYPAUSE].handler_block(self._button_handlers[HeaderBar.SIGNAL_PLAYPAUSE]):
|
||||
self._buttons[HeaderBar.SIGNAL_PLAYPAUSE].handler_block_by_func(
|
||||
self._button_handlers[HeaderBar.SIGNAL_PLAYPAUSE]
|
||||
)
|
||||
self._buttons[HeaderBar.SIGNAL_PLAYPAUSE].set_active(True)
|
||||
self._buttons[HeaderBar.SIGNAL_PLAYPAUSE].handler_unblock_by_func(
|
||||
self._button_handlers[HeaderBar.SIGNAL_PLAYPAUSE]
|
||||
)
|
||||
|
||||
|
||||
def set_pause(self):
|
||||
with self._buttons[HeaderBar.SIGNAL_PLAYPAUSE].handler_block(self._button_handlers[HeaderBar.SIGNAL_PLAYPAUSE]):
|
||||
self._buttons[HeaderBar.SIGNAL_PLAYPAUSE].handler_block_by_func(
|
||||
self._button_handlers[HeaderBar.SIGNAL_PLAYPAUSE]
|
||||
)
|
||||
self._buttons[HeaderBar.SIGNAL_PLAYPAUSE].set_active(False)
|
||||
self._buttons[HeaderBar.SIGNAL_PLAYPAUSE].handler_unblock_by_func(
|
||||
self._button_handlers[HeaderBar.SIGNAL_PLAYPAUSE]
|
||||
)
|
||||
|
||||
|
||||
def set_volume(self, volume):
|
||||
|
|
@ -532,141 +545,94 @@ class HeaderBar(mcg.Base, Gtk.HeaderBar):
|
|||
self._buttons[HeaderBar.SIGNAL_SET_VOLUME].set_visible(False)
|
||||
|
||||
|
||||
def _callback_from_widget(self, widget, signal, *data):
|
||||
self._callback(signal, *data)
|
||||
def _callback_from_widget(self, widget):
|
||||
if widget is self._buttons[HeaderBar.SIGNAL_CONNECT]:
|
||||
self._callback(self.SIGNAL_CONNECT)
|
||||
elif widget is self._buttons[HeaderBar.SIGNAL_PLAYPAUSE]:
|
||||
self._callback(self.SIGNAL_PLAYPAUSE)
|
||||
|
||||
|
||||
|
||||
|
||||
class InfoBar(Gtk.InfoBar):
|
||||
_RESPONSE_CLOSE = 1
|
||||
|
||||
|
||||
def __init__(self):
|
||||
Gtk.InfoBar.__init__(self)
|
||||
|
||||
class InfoBar():
|
||||
def __init__(self, builder):
|
||||
# Widgets
|
||||
self.add_button(Gtk.STOCK_CLOSE, InfoBar._RESPONSE_CLOSE)
|
||||
self._message_label = Gtk.Label()
|
||||
self._message_label.show()
|
||||
self.get_content_area().add(self._message_label)
|
||||
|
||||
# Signals
|
||||
self.connect('close', self.on_response, InfoBar._RESPONSE_CLOSE)
|
||||
self.connect('response', self.on_response)
|
||||
self._revealer = builder.get_object('server-info-revealer')
|
||||
self._bar = builder.get_object('server-info-bar')
|
||||
self._message_label = builder.get_object('server-info-label')
|
||||
|
||||
|
||||
def on_response(self, widget, response):
|
||||
if response == InfoBar._RESPONSE_CLOSE:
|
||||
def get_signal_handlers(self):
|
||||
return {
|
||||
'on_server-info-bar_close': self.on_close,
|
||||
'on_server-info-bar_response': self.on_response
|
||||
}
|
||||
|
||||
|
||||
def on_close(self, *args):
|
||||
self.hide()
|
||||
|
||||
|
||||
def on_response(self, widget, response):
|
||||
self.hide()
|
||||
|
||||
|
||||
def hide(self):
|
||||
self._revealer.set_reveal_child(False)
|
||||
|
||||
|
||||
def show_error(self, message):
|
||||
self.set_message_type(Gtk.MessageType.ERROR)
|
||||
self._bar.set_message_type(Gtk.MessageType.ERROR)
|
||||
self._message_label.set_text(message)
|
||||
self._revealer.set_reveal_child(True)
|
||||
|
||||
|
||||
|
||||
|
||||
class Panel(mcg.Base):
|
||||
|
||||
|
||||
def __init__(self):
|
||||
mcg.Base.__init__(self)
|
||||
|
||||
|
||||
def get_name(self):
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
def get_title(self):
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
|
||||
|
||||
class ConnectionPanel(Panel, Gtk.VBox):
|
||||
class ConnectionPanel(mcg.Base):
|
||||
SIGNAL_CONNECTION_CHANGED = 'connection-changed'
|
||||
|
||||
|
||||
def __init__(self):
|
||||
Panel.__init__(self)
|
||||
Gtk.VBox.__init__(self)
|
||||
def __init__(self, builder):
|
||||
mcg.Base.__init__(self)
|
||||
self._services = Gtk.ListStore(str, str, int)
|
||||
self._profile = None
|
||||
|
||||
# Widgets
|
||||
hbox = Gtk.HBox()
|
||||
self.pack_start(hbox, True, False, 0)
|
||||
grid = Gtk.Grid()
|
||||
grid.set_column_spacing(5)
|
||||
grid.set_column_homogeneous(True)
|
||||
hbox.pack_start(grid, True, False, 0)
|
||||
self._panel = builder.get_object('server-panel')
|
||||
# Zeroconf
|
||||
zeroconf_box = Gtk.HBox()
|
||||
grid.add(zeroconf_box)
|
||||
# Zeroconf list
|
||||
self._zeroconf_list = Gtk.TreeView(self._services)
|
||||
self._zeroconf_list.get_selection().set_mode(Gtk.SelectionMode.SINGLE)
|
||||
self._zeroconf_list = builder.get_object('server-zeroconf-list')
|
||||
self._zeroconf_list.set_model(self._services)
|
||||
renderer = Gtk.CellRendererText()
|
||||
column = Gtk.TreeViewColumn("Zeroconf", renderer, text=0)
|
||||
self._zeroconf_list.append_column(column)
|
||||
zeroconf_box.pack_start(self._zeroconf_list, True, True, 0)
|
||||
# Separator
|
||||
separator = Gtk.Separator.new(Gtk.Orientation.VERTICAL)
|
||||
zeroconf_box.pack_end(separator, False, False, 5)
|
||||
# Connection grid
|
||||
connection_grid = Gtk.Grid()
|
||||
grid.attach_next_to(connection_grid, zeroconf_box, Gtk.PositionType.RIGHT, 1, 1)
|
||||
# Host
|
||||
host_label = Gtk.Label("Host:")
|
||||
host_label.set_alignment(0, 0.5)
|
||||
connection_grid.add(host_label)
|
||||
self._host_entry = Gtk.Entry()
|
||||
self._host_entry.set_text("localhost")
|
||||
connection_grid.attach_next_to(self._host_entry, host_label, Gtk.PositionType.BOTTOM, 1, 1)
|
||||
self._host_entry = builder.get_object('server-host')
|
||||
# Port
|
||||
port_label = Gtk.Label("Port:")
|
||||
port_label.set_alignment(0, 0.5)
|
||||
connection_grid.attach_next_to(port_label, self._host_entry, Gtk.PositionType.BOTTOM, 1, 1)
|
||||
adjustment = Gtk.Adjustment(6600, 1024, 9999, 1, 10, 10)
|
||||
self._port_spinner = Gtk.SpinButton()
|
||||
self._port_spinner.set_adjustment(adjustment)
|
||||
connection_grid.attach_next_to(self._port_spinner, port_label, Gtk.PositionType.BOTTOM, 1, 1)
|
||||
self._port_spinner = builder.get_object('server-port')
|
||||
# Passwort
|
||||
password_label = Gtk.Label("Password:")
|
||||
password_label.set_alignment(0, 0.5)
|
||||
connection_grid.attach_next_to(password_label, self._port_spinner, Gtk.PositionType.BOTTOM, 1, 1)
|
||||
self._password_entry = Gtk.Entry()
|
||||
self._password_entry.set_input_purpose(Gtk.InputPurpose.PASSWORD)
|
||||
self._password_entry.set_visibility(False)
|
||||
connection_grid.attach_next_to(self._password_entry, password_label, Gtk.PositionType.BOTTOM, 1, 1)
|
||||
self._password_entry = builder.get_object('server-password')
|
||||
# Image dir
|
||||
image_dir_label = Gtk.Label("Image Dir:")
|
||||
image_dir_label.set_alignment(0, 0.5)
|
||||
connection_grid.attach_next_to(image_dir_label, self._password_entry, Gtk.PositionType.BOTTOM, 1, 1)
|
||||
self._image_dir_entry = Gtk.Entry()
|
||||
connection_grid.attach_next_to(self._image_dir_entry, image_dir_label, Gtk.PositionType.BOTTOM, 1, 1)
|
||||
self._image_dir_entry = builder.get_object('server-image-dir')
|
||||
|
||||
# Zeroconf provider
|
||||
self._zeroconf_provider = ZeroconfProvider()
|
||||
self._zeroconf_provider.connect_signal(ZeroconfProvider.SIGNAL_SERVICE_NEW, self.on_new_service)
|
||||
|
||||
# Signals
|
||||
self._zeroconf_list.get_selection().connect('changed', self.on_service_selected)
|
||||
self._zeroconf_list.connect('focus-out-event', self.on_zeroconf_list_outfocused)
|
||||
self._host_entry.connect('focus-out-event', self.on_host_entry_outfocused)
|
||||
self._port_spinner.connect('value-changed', self.on_port_spinner_value_changed)
|
||||
self._password_entry.connect('focus-out-event', self.on_password_entry_outfocused)
|
||||
self._image_dir_entry.connect('focus-out-event', self.on_image_dir_entry_outfocused)
|
||||
|
||||
def get(self):
|
||||
return self._panel
|
||||
|
||||
|
||||
def get_name(self):
|
||||
return 'connection'
|
||||
|
||||
|
||||
def get_title(self):
|
||||
return "Server"
|
||||
def get_signal_handlers(self):
|
||||
return {
|
||||
'on_server-zeroconf-list-selection_changed': self.on_service_selected,
|
||||
'on_server-zeroconf-list_focus_out_event': self.on_zeroconf_list_outfocused,
|
||||
'on_server-host_focus_out_event': self.on_host_entry_outfocused,
|
||||
'on_server-port_value_changed': self.on_port_spinner_value_changed,
|
||||
'on_server-password_focus_out_event': self.on_password_entry_outfocused,
|
||||
'on_server-image-dir_focus_out_event': self.on_image_dir_entry_outfocused
|
||||
}
|
||||
|
||||
|
||||
def on_new_service(self, service):
|
||||
|
|
@ -745,64 +711,44 @@ class ConnectionPanel(Panel, Gtk.VBox):
|
|||
|
||||
|
||||
|
||||
class CoverPanel(Panel, Gtk.VBox):
|
||||
class CoverPanel(mcg.Base):
|
||||
SIGNAL_TOGGLE_FULLSCREEN = 'toggle-fullscreen'
|
||||
SIGNAL_SET_SONG = 'set-song'
|
||||
|
||||
|
||||
def __init__(self):
|
||||
Panel.__init__(self)
|
||||
Gtk.VBox.__init__(self)
|
||||
def __init__(self, builder):
|
||||
mcg.Base.__init__(self)
|
||||
|
||||
self._current_album = None
|
||||
self._cover_pixbuf = None
|
||||
self._timer = None
|
||||
self._properties = {}
|
||||
|
||||
# Widgets
|
||||
self._current_box = Gtk.Box(Gtk.Orientation.HORIZONTAL)
|
||||
self._current_box.set_halign(Gtk.Align.FILL)
|
||||
self._current_box.set_homogeneous(True)
|
||||
self.pack_start(self._current_box, True, True, 10)
|
||||
self._panel = builder.get_object('cover-panel')
|
||||
# Cover
|
||||
self._cover_image = Gtk.Image()
|
||||
self._cover_box = Gtk.EventBox()
|
||||
self._cover_box.add(self._cover_image)
|
||||
self._cover_scroll = Gtk.ScrolledWindow()
|
||||
self._cover_scroll.add(self._cover_box)
|
||||
self._current_box.pack_start(self._cover_scroll, True, True, 10)
|
||||
self._cover_scroll = builder.get_object('cover-scroll')
|
||||
self._cover_image = builder.get_object('cover-image')
|
||||
# Songs
|
||||
self._songs_scale = Gtk.VScale()
|
||||
self._songs_scale.set_halign(Gtk.Align.START)
|
||||
self._songs_scale.set_vexpand(True)
|
||||
self._songs_scale.set_digits(0)
|
||||
self._songs_scale.set_draw_value(False)
|
||||
self._songs_scale = builder.get_object('cover-songs')
|
||||
self._songs_scale.override_color(Gtk.StateFlags.NORMAL, Gdk.RGBA(0, 0, 0, 1))
|
||||
self._current_box.pack_end(self._songs_scale, True, True, 10)
|
||||
# Album Infos
|
||||
self._info_grid = Gtk.Grid()
|
||||
self._info_grid.set_halign(Gtk.Align.CENTER)
|
||||
self._info_grid.set_row_spacing(5)
|
||||
self._album_title_label = Gtk.Label()
|
||||
self._info_grid.add(self._album_title_label)
|
||||
self._album_date_label = Gtk.Label()
|
||||
self._info_grid.attach_next_to(self._album_date_label, self._album_title_label, Gtk.PositionType.BOTTOM, 1, 1)
|
||||
self._album_artist_label = Gtk.Label()
|
||||
self._info_grid.attach_next_to(self._album_artist_label, self._album_date_label, Gtk.PositionType.BOTTOM, 1, 1)
|
||||
self.pack_end(self._info_grid, False, True, 10)
|
||||
|
||||
# Signals
|
||||
self._cover_box.connect('button-press-event', self.on_cover_box_pressed)
|
||||
self._cover_scroll.connect('size-allocate', self.on_cover_size_allocate)
|
||||
self._songs_scale.connect('button-press-event', self.on_songs_start_change)
|
||||
self._songs_scale.connect('button-release-event', self.on_songs_change)
|
||||
self._album_title_label = builder.get_object('cover-album')
|
||||
self._album_date_label = builder.get_object('cover-date')
|
||||
self._album_artist_label = builder.get_object('cover-artist')
|
||||
|
||||
|
||||
def get_name(self):
|
||||
return 'cover'
|
||||
def get(self):
|
||||
return self._panel
|
||||
|
||||
|
||||
def get_title(self):
|
||||
return "Cover"
|
||||
def get_signal_handlers(self):
|
||||
return {
|
||||
'on_cover-box_button_press_event': self.on_cover_box_pressed,
|
||||
'on_cover-scroll_size_allocate': self.on_cover_size_allocate,
|
||||
'on_cover-songs_button_press_event': self.on_songs_start_change,
|
||||
'on_cover-songs_button_release_event': self.on_songs_change
|
||||
}
|
||||
|
||||
|
||||
def on_cover_box_pressed(self, widget, event):
|
||||
|
|
@ -977,13 +923,12 @@ class CoverPanel(Panel, Gtk.VBox):
|
|||
|
||||
|
||||
|
||||
class PlaylistPanel(Panel, Gtk.VBox):
|
||||
class PlaylistPanel(mcg.Base):
|
||||
SIGNAL_CLEAR_PLAYLIST = 'clear-playlist'
|
||||
|
||||
|
||||
def __init__(self):
|
||||
Panel.__init__(self)
|
||||
Gtk.VBox.__init__(self)
|
||||
def __init__(self, builder):
|
||||
mcg.Base.__init__(self)
|
||||
self._host = None
|
||||
self._item_size = 150
|
||||
self._playlist = None
|
||||
|
|
@ -991,48 +936,28 @@ class PlaylistPanel(Panel, Gtk.VBox):
|
|||
self._playlist_stop = threading.Event()
|
||||
self._icon_theme = Gtk.IconTheme.get_default()
|
||||
|
||||
# Toolbar
|
||||
self._playlist_toolbar = Gtk.Toolbar()
|
||||
self.pack_start(self._playlist_toolbar, False, True, 0)
|
||||
# Toolbar: Clear Button
|
||||
self._clear_playlist_button = Gtk.ToolButton(Gtk.STOCK_CLEAR)
|
||||
self._playlist_toolbar.add(self._clear_playlist_button)
|
||||
# Widgets
|
||||
self._panel = builder.get_object('playlist-panel')
|
||||
# Clear button
|
||||
self._playlist_clear_button = builder.get_object('playlist-clear')
|
||||
# Playlist Grid: Model
|
||||
self._playlist_grid_model = Gtk.ListStore(GdkPixbuf.Pixbuf, str, str)
|
||||
# Playlist Grid
|
||||
self._playlist_grid = Gtk.IconView(self._playlist_grid_model)
|
||||
self._playlist_grid = builder.get_object('playlist-iconview')
|
||||
self._playlist_grid.set_model(self._playlist_grid_model)
|
||||
self._playlist_grid.set_pixbuf_column(0)
|
||||
self._playlist_grid.set_text_column(-1)
|
||||
self._playlist_grid.set_tooltip_column(1)
|
||||
self._playlist_grid.set_margin(0)
|
||||
self._playlist_grid.set_spacing(0)
|
||||
self._playlist_grid.set_row_spacing(0)
|
||||
self._playlist_grid.set_column_spacing(0)
|
||||
self._playlist_grid.set_item_padding(5)
|
||||
self._playlist_grid.set_reorderable(False)
|
||||
self._playlist_grid.set_item_width(-1)
|
||||
self._playlist_grid.set_selection_mode(Gtk.SelectionMode.SINGLE)
|
||||
self._playlist_scroll = Gtk.ScrolledWindow()
|
||||
self._playlist_scroll.add(self._playlist_grid)
|
||||
self.pack_end(self._playlist_scroll, True, True, 0)
|
||||
self.show_all();
|
||||
|
||||
# Properties
|
||||
self._playlist_toolbar.get_style_context().add_class(Window.STYLE_CLASS_NO_BG)
|
||||
self._playlist_toolbar.get_style_context().add_class(Window.STYLE_CLASS_NO_BORDER)
|
||||
self._playlist_grid.get_style_context().add_class(Window.STYLE_CLASS_NO_BG)
|
||||
self._playlist_grid.get_style_context().add_class(Window.STYLE_CLASS_NO_BORDER)
|
||||
|
||||
# Signals
|
||||
self._clear_playlist_button.connect('clicked' ,self._callback_from_widget, PlaylistPanel.SIGNAL_CLEAR_PLAYLIST)
|
||||
|
||||
|
||||
def get_name(self):
|
||||
return "playlist"
|
||||
def get(self):
|
||||
return self._panel
|
||||
|
||||
|
||||
def get_title(self):
|
||||
return "Playlist"
|
||||
def get_signal_handlers(self):
|
||||
return {
|
||||
'on_playlist-clear_clicked': self._callback_from_widget
|
||||
}
|
||||
|
||||
|
||||
def set_item_size(self, item_size):
|
||||
|
|
@ -1100,13 +1025,14 @@ class PlaylistPanel(Panel, Gtk.VBox):
|
|||
self.set_playlist(self._host, self._playlist)
|
||||
|
||||
|
||||
def _callback_from_widget(self, widget, signal, *data):
|
||||
self._callback(signal, *data)
|
||||
def _callback_from_widget(self, widget):
|
||||
if widget is self._playlist_clear_button:
|
||||
self._callback(PlaylistPanel.SIGNAL_CLEAR_PLAYLIST)
|
||||
|
||||
|
||||
|
||||
|
||||
class LibraryPanel(Panel, Gtk.VBox):
|
||||
class LibraryPanel(mcg.Base):
|
||||
SIGNAL_UPDATE = 'update'
|
||||
SIGNAL_PLAY = 'play'
|
||||
SIGNAL_ITEM_SIZE_CHANGED = 'item-size-changed'
|
||||
|
|
@ -1114,9 +1040,8 @@ class LibraryPanel(Panel, Gtk.VBox):
|
|||
SIGNAL_SORT_TYPE_CHANGED = 'sort-type-changed'
|
||||
|
||||
|
||||
def __init__(self):
|
||||
Panel.__init__(self)
|
||||
Gtk.VBox.__init__(self)
|
||||
def __init__(self, builder):
|
||||
mcg.Base.__init__(self)
|
||||
self._buttons = {}
|
||||
self._albums = None
|
||||
self._host = "localhost"
|
||||
|
|
@ -1131,53 +1056,30 @@ class LibraryPanel(Panel, Gtk.VBox):
|
|||
self._icon_theme = Gtk.IconTheme.get_default()
|
||||
|
||||
# Widgets
|
||||
self._panel = builder.get_object('library-panel')
|
||||
# Progress Bar
|
||||
self._progress_bar = Gtk.ProgressBar()
|
||||
self._progress_revealer = builder.get_object('library-progress-revealer')
|
||||
self._progress_bar = builder.get_object('library-progress')
|
||||
# Toolbar
|
||||
self._library_toolbar = Gtk.HeaderBar()
|
||||
self.pack_start(self._library_toolbar, False, True, 0)
|
||||
# Toolbar: buttons left
|
||||
# Toolbar: buttons left: Update Button
|
||||
self._buttons[LibraryPanel.SIGNAL_UPDATE] = Gtk.ToolButton(Gtk.STOCK_REFRESH)
|
||||
self._library_toolbar.pack_start(self._buttons[LibraryPanel.SIGNAL_UPDATE])
|
||||
# Toolbar: Filter Entry
|
||||
self._filter_entry = Gtk.SearchEntry()
|
||||
self._filter_entry.set_placeholder_text("search library")
|
||||
self._library_toolbar.set_custom_title(self._filter_entry)
|
||||
# Toolbar: buttons right
|
||||
self._right_toolbar = Gtk.Toolbar()
|
||||
self._right_toolbar.set_show_arrow(False)
|
||||
self._right_toolbar.get_style_context().add_class(Window.STYLE_CLASS_NO_BG)
|
||||
self._library_toolbar.pack_end(self._right_toolbar)
|
||||
# Toolbar: buttons right: Grid Scale
|
||||
self._grid_scale = Gtk.HScale()
|
||||
self._grid_scale.set_range(100, 1000)
|
||||
self._grid_scale.set_round_digits(0)
|
||||
# Filter entry
|
||||
self._filter_entry = builder.get_object('library-filter')
|
||||
# Grid scale
|
||||
self._grid_scale = builder.get_object('library-grid-scale')
|
||||
self._grid_scale.set_value(self._item_size)
|
||||
self._grid_scale.set_size_request(100, -1)
|
||||
self._grid_scale.set_draw_value(False)
|
||||
item = Gtk.ToolItem()
|
||||
item.add(self._grid_scale)
|
||||
self._right_toolbar.add(item)
|
||||
# Toolbar: buttons right: Library Sort Menu
|
||||
# Sort menu
|
||||
library_sort_store = Gtk.ListStore(str, str)
|
||||
library_sort_store.append([mcg.MCGAlbum.SORT_BY_ARTIST, "sort by artist"])
|
||||
library_sort_store.append([mcg.MCGAlbum.SORT_BY_TITLE, "sort by title"])
|
||||
library_sort_store.append([mcg.MCGAlbum.SORT_BY_YEAR, "sort by year"])
|
||||
self._library_sort_combo = Gtk.ComboBox.new_with_model(library_sort_store)
|
||||
self._library_sort_combo = builder.get_object('library-sort')
|
||||
self._library_sort_combo.set_model(library_sort_store)
|
||||
renderer_text = Gtk.CellRendererText()
|
||||
self._library_sort_combo.pack_start(renderer_text, True)
|
||||
self._library_sort_combo.add_attribute(renderer_text, "text", 1)
|
||||
self._library_sort_combo.set_id_column(0)
|
||||
self._library_sort_combo.set_active_id(self._sort_order)
|
||||
item = Gtk.ToolItem()
|
||||
item.add(self._library_sort_combo)
|
||||
self._right_toolbar.add(item)
|
||||
# Toolbar: buttons right: Library Sort Type
|
||||
self._library_sort_type_button = Gtk.ToggleToolButton.new_from_stock(Gtk.STOCK_SORT_ASCENDING)
|
||||
self._library_sort_type_button.set_active(True)
|
||||
self._library_sort_type_button.set_stock_id(Gtk.STOCK_SORT_DESCENDING)
|
||||
self._right_toolbar.add(self._library_sort_type_button)
|
||||
# Sort type
|
||||
self._library_sort_type_button = builder.get_object('library-sort-order')
|
||||
# Library Grid: Model
|
||||
self._library_grid_model = Gtk.ListStore(GdkPixbuf.Pixbuf, str, str)
|
||||
self._library_grid_model.set_sort_func(2, self.compare_albums, self._sort_order)
|
||||
|
|
@ -1185,46 +1087,31 @@ class LibraryPanel(Panel, Gtk.VBox):
|
|||
self._library_grid_filter = self._library_grid_model.filter_new()
|
||||
self._library_grid_filter.set_visible_func(self.on_filter_visible)
|
||||
# Library Grid
|
||||
self._library_grid = Gtk.IconView(self._library_grid_filter)
|
||||
# self._library_grid.pack_end(text_renderer, False)
|
||||
# self._library_grid.add_attribute(text_renderer, "markup", 0)
|
||||
self._library_grid = builder.get_object('library-iconview')
|
||||
self._library_grid.set_model(self._library_grid_filter)
|
||||
self._library_grid.set_pixbuf_column(0)
|
||||
self._library_grid.set_text_column(-1)
|
||||
self._library_grid.set_tooltip_column(1)
|
||||
self._library_grid.set_margin(0)
|
||||
self._library_grid.set_spacing(0)
|
||||
self._library_grid.set_row_spacing(0)
|
||||
self._library_grid.set_column_spacing(0)
|
||||
self._library_grid.set_item_padding(5)
|
||||
self._library_grid.set_reorderable(False)
|
||||
self._library_grid.set_item_width(-1)
|
||||
self._library_grid.set_selection_mode(Gtk.SelectionMode.SINGLE)
|
||||
self._library_scroll = Gtk.ScrolledWindow()
|
||||
self._library_scroll.add(self._library_grid)
|
||||
self.pack_end(self._library_scroll, True, True, 0)
|
||||
|
||||
# Properties
|
||||
self._library_toolbar.get_style_context().add_class(Window.STYLE_CLASS_NO_BG)
|
||||
self._library_toolbar.get_style_context().add_class(Window.STYLE_CLASS_NO_BORDER)
|
||||
self._library_grid.get_style_context().add_class(Window.STYLE_CLASS_NO_BG)
|
||||
self._library_grid.get_style_context().add_class(Window.STYLE_CLASS_NO_BORDER)
|
||||
|
||||
# Signals
|
||||
self._buttons[LibraryPanel.SIGNAL_UPDATE].connect('clicked', self._callback_from_widget, self.SIGNAL_UPDATE)
|
||||
self._grid_scale.connect('change-value', self.on_grid_scale_change)
|
||||
self._grid_scale.connect('button-release-event', self.on_grid_scale_changed)
|
||||
self._library_sort_combo.connect("changed", self.on_library_sort_combo_changed)
|
||||
self._library_sort_type_button.connect('clicked', self.on_library_sort_type_button_activated)
|
||||
self._filter_entry.connect('search-changed', self.on_filter_entry_changed)
|
||||
self._library_grid.connect('item-activated', self.on_library_grid_clicked)
|
||||
|
||||
|
||||
def get_name(self):
|
||||
return "library"
|
||||
def get(self):
|
||||
return self._panel
|
||||
|
||||
|
||||
def get_title(self):
|
||||
return "Library"
|
||||
def get_signal_handlers(self):
|
||||
return {
|
||||
'on_library-update_clicked': self.on_update_clicked,
|
||||
'on_library-grid-scale_change_value': self.on_grid_scale_change,
|
||||
'on_library-grid-scale_button_release_event': self.on_grid_scale_changed,
|
||||
'on_library-sort_changed': self.on_library_sort_combo_changed,
|
||||
'on_library-sort-order_clicked': self.on_library_sort_type_button_activated,
|
||||
'on_library-filter_search_changed': self.on_filter_entry_changed,
|
||||
'on_library-iconview_item_activated': self.on_library_grid_clicked
|
||||
}
|
||||
|
||||
|
||||
def on_update_clicked(self, widget):
|
||||
self._callback(self.SIGNAL_UPDATE)
|
||||
|
||||
|
||||
def on_filter_visible(self, model, iter, data):
|
||||
|
|
@ -1295,9 +1182,11 @@ class LibraryPanel(Panel, Gtk.VBox):
|
|||
|
||||
|
||||
def set_sort_order(self, sort_order):
|
||||
if self._sort_order != sort_order:
|
||||
result = self._library_sort_combo.set_active_id(sort_order)
|
||||
if self._sort_order != sort_order:
|
||||
self._sort_order = sort_order
|
||||
self._library_sort_combo.set_active_id(sort_order)
|
||||
self._library_grid_model.set_sort_func(2, self.compare_albums, self._sort_order)
|
||||
|
||||
|
||||
def get_sort_order(self):
|
||||
|
|
@ -1307,11 +1196,17 @@ class LibraryPanel(Panel, Gtk.VBox):
|
|||
def set_sort_type(self, sort_type):
|
||||
if self._sort_type != sort_type:
|
||||
if sort_type:
|
||||
self._sort_type = Gtk.SortType.DESCENDING
|
||||
sort_type_gtk = Gtk.SortType.DESCENDING
|
||||
stock_id = Gtk.STOCK_SORT_DESCENDING
|
||||
self._library_sort_type_button.set_active(True)
|
||||
else:
|
||||
self._sort_type = Gtk.SortType.ASCENDING
|
||||
sort_type_gtk = Gtk.SortType.ASCENDING
|
||||
self._library_sort_type_button.set_active(False)
|
||||
stock_id = Gtk.STOCK_SORT_ASCENDING
|
||||
if self._sort_type != sort_type_gtk:
|
||||
self._sort_type = sort_type_gtk
|
||||
self._library_sort_type_button.set_stock_id(stock_id)
|
||||
self._library_grid_model.set_sort_column_id(2, sort_type)
|
||||
|
||||
|
||||
def get_sort_type(self):
|
||||
|
|
@ -1341,11 +1236,8 @@ class LibraryPanel(Panel, Gtk.VBox):
|
|||
self._library_lock.acquire()
|
||||
self._library_stop.clear()
|
||||
self._albums = albums
|
||||
if len(self.get_children()) > 1:
|
||||
GObject.idle_add(self.remove, self.get_children()[0])
|
||||
self._progress_revealer.set_reveal_child(True)
|
||||
GObject.idle_add(self._progress_bar.set_fraction, 0.0)
|
||||
GObject.idle_add(self.pack_start, self._progress_bar, False, True, 0)
|
||||
GObject.idle_add(self.show_all)
|
||||
self._library_grid.set_model(None)
|
||||
self._library_grid.freeze_child_notify()
|
||||
self._library_grid_model.clear()
|
||||
|
|
@ -1385,10 +1277,7 @@ class LibraryPanel(Panel, Gtk.VBox):
|
|||
self._library_grid.thaw_child_notify()
|
||||
self._library_grid.set_item_width(-1)
|
||||
self._library_lock.release()
|
||||
if len(self.get_children()) > 1:
|
||||
GObject.idle_add(self.remove, self.get_children()[0])
|
||||
GObject.idle_add(self.pack_start, self._library_toolbar, False, True, 0)
|
||||
GObject.idle_add(self.show_all)
|
||||
self._progress_revealer.set_reveal_child(False)
|
||||
|
||||
|
||||
def _set_widget_grid_size(self, grid_widget, size, vertical):
|
||||
|
|
@ -1451,25 +1340,18 @@ class LibraryPanel(Panel, Gtk.VBox):
|
|||
self.set_albums(self._host, self._albums)
|
||||
|
||||
|
||||
def _callback_from_widget(self, widget, signal, *data):
|
||||
self._callback(signal, *data)
|
||||
|
||||
|
||||
|
||||
|
||||
class StackSwitcher(mcg.Base, Gtk.StackSwitcher):
|
||||
class StackSwitcher(mcg.Base):
|
||||
SIGNAL_STACK_SWITCHED = 'stack-switched'
|
||||
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self, builder):
|
||||
mcg.Base.__init__(self)
|
||||
Gtk.StackSwitcher.__init__(self)
|
||||
|
||||
self._temp_button = None
|
||||
|
||||
|
||||
def set_stack(self, stack):
|
||||
super().set_stack(stack)
|
||||
for child in self.get_children():
|
||||
self._stack_switcher = builder.get_object('header-panelswitcher')
|
||||
for child in self._stack_switcher.get_children():
|
||||
if type(child) is Gtk.RadioButton:
|
||||
child.connect('clicked', self.on_clicked)
|
||||
|
||||
|
|
@ -1482,6 +1364,10 @@ class StackSwitcher(mcg.Base, Gtk.StackSwitcher):
|
|||
self._callback(StackSwitcher.SIGNAL_STACK_SWITCHED, self)
|
||||
|
||||
|
||||
def get(self):
|
||||
return self._stack_switcher
|
||||
|
||||
|
||||
|
||||
|
||||
class ZeroconfProvider(mcg.Base):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue