皆さんこんにちは!私の最初の投稿では、Vala言語で簡単なラジオを作成することについて話したいと思います。私はプログラマーではなくアマチュアであり、すべての開発をJavaで作成しましたが、コンピューター、つまり古き良きDebian、さらにはGNOMEでもGNU / Linuxを使用しているので、何か-このシステムのために何でも。
トレーニング
否や言うほどない!ネイティブテキストエディタGEditで書くことにしました。GTK開発用にインストールされたコンパイラとパッケージ:
sudo apt install valac libgtk-3-dev
GStreamer開発者パッケージも必要です。それもインストールしましょう:
sudo apt install libgstreamer1.0-dev
進む!エディターで、組み込み端末のサポートを有効にし、端末が表示される下部パネルを表示する必要があります。また、便宜上、単語補完、括弧、およびその他の機能を含める必要があります。それらはすべてモジュールのリストにあります。エディターの設定で見つけることができます。とても便利なもの。本質的に、彼らは通常のテキストエディタを基本的な開発環境に変えます。
グラフィカルインターフェイス
ファイル
これで、エディターの準備が整いました。どこから始めますか?もちろん、インターフェースから!エディターでペンを使ってGUIを作成します。しかし、最初にコード自体について。2つのファイルがあります。1つはApplication.valaと呼ばれ、次の内容が含まれています。
namespace Raddiola {
public class Application : Gtk.Application {
public MainWindow app_window;
public Application() {
Object(flags: ApplicationFlags.FLAGS_NONE, application_id: "com.github.alexkdeveloper.raddiola");
}
protected override void activate() {
if(get_windows().length() > 0) {
app_window.present();
return;
}
app_window = new MainWindow(this);
app_window.show_all();
}
public static int main(string[] args) {
Gst.init (ref args);
var app = new Raddiola.Application();
return app.run(args);
}
}
}
. MainWindow.vala .
, . , .
, "play" "stop", . . :
, . :
, :
using Gtk;
using Gst;
namespace Raddiola {
public class MainWindow : Gtk.ApplicationWindow {
private Stack stack;
private Box vbox_player_page;
private Box vbox_edit_page;
private dynamic Element player;
private Gtk.ListStore list_store;
private TreeView tree_view;
private GLib.List<string> list;
private Entry entry_name;
private Entry entry_url;
private Button back_button;
private Button add_button;
private Button delete_button;
private Button edit_button;
private Button play_button;
private Button stop_button;
private string directory_path;
private string item;
private int mode;
public MainWindow(Gtk.Application application) {
GLib.Object(application: application,
title: "Raddiola",
window_position: WindowPosition.CENTER,
resizable: true,
height_request: 500,
width_request: 500,
border_width: 10);
}
construct {
Gtk.HeaderBar headerbar = new Gtk.HeaderBar();
headerbar.get_style_context().add_class(Gtk.STYLE_CLASS_FLAT);
headerbar.show_close_button = true;
set_titlebar(headerbar);
back_button = new Gtk.Button ();
back_button.set_image (new Gtk.Image.from_icon_name ("go-previous-symbolic", Gtk.IconSize.SMALL_TOOLBAR));
back_button.vexpand = false;
add_button = new Gtk.Button ();
add_button.set_image (new Gtk.Image.from_icon_name ("list-add-symbolic", Gtk.IconSize.SMALL_TOOLBAR));
add_button.vexpand = false;
delete_button = new Gtk.Button ();
delete_button.set_image (new Gtk.Image.from_icon_name ("list-remove-symbolic", Gtk.IconSize.SMALL_TOOLBAR));
delete_button.vexpand = false;
edit_button = new Gtk.Button ();
edit_button.set_image (new Gtk.Image.from_icon_name ("document-edit-symbolic", Gtk.IconSize.SMALL_TOOLBAR));
edit_button.vexpand = false;
play_button = new Gtk.Button();
play_button.set_image (new Gtk.Image.from_icon_name ("media-playback-start-symbolic", Gtk.IconSize.SMALL_TOOLBAR));
play_button.vexpand = false;
stop_button = new Gtk.Button();
stop_button.set_image (new Gtk.Image.from_icon_name ("media-playback-stop-symbolic", Gtk.IconSize.SMALL_TOOLBAR));
stop_button.vexpand = false;
. , .
back_button.set_tooltip_text("back");
add_button.set_tooltip_text("add station");
delete_button.set_tooltip_text("delete station");
edit_button.set_tooltip_text("edit station");
play_button.set_tooltip_text("play");
stop_button.set_tooltip_text("stop");
back_button.clicked.connect(on_back_clicked);
add_button.clicked.connect(on_add_clicked);
delete_button.clicked.connect(on_delete_dialog);
edit_button.clicked.connect(on_edit_clicked);
play_button.clicked.connect(on_play_station);
stop_button.clicked.connect(on_stop_station);
headerbar.pack_start(back_button);
headerbar.pack_start(add_button);
headerbar.pack_start(delete_button);
headerbar.pack_start(edit_button);
headerbar.pack_end(stop_button);
headerbar.pack_end(play_button);
, set_widget_visible
:
set_widget_visible(back_button,false);
set_widget_visible(stop_button,false);
:
private void set_widget_visible (Gtk.Widget widget, bool visible) {
widget.no_show_all = !visible;
widget.visible = visible;
}
, . . :
stack = new Stack();
stack.set_transition_duration (600);
stack.set_transition_type (StackTransitionType.SLIDE_LEFT_RIGHT);
add (stack);//
list_store = new Gtk.ListStore(Columns.N_COLUMNS, typeof(string));//
tree_view = new TreeView.with_model(list_store);
var text = new CellRendererText ();
var column = new TreeViewColumn ();
column.pack_start (text, true);
column.add_attribute (text, "markup", Columns.TEXT);
tree_view.append_column (column);
tree_view.set_headers_visible (false);
tree_view.cursor_changed.connect(on_select_item);
var scroll = new ScrolledWindow (null, null);
scroll.set_policy (PolicyType.AUTOMATIC, PolicyType.AUTOMATIC);
scroll.add (this.tree_view);
vbox_player_page = new Box(Orientation.VERTICAL,20);
vbox_player_page.pack_start(scroll,true,true,0);
stack.add(vbox_player_page);//
. . , URL. , .
entry_name = new Entry();
entry_name.set_icon_from_icon_name (Gtk.EntryIconPosition.SECONDARY, "edit-clear-symbolic");
entry_name.icon_press.connect ((pos, event) => {
if (pos == Gtk.EntryIconPosition.SECONDARY) {
entry_name.set_text("");//
}
});
var label_name = new Label.with_mnemonic ("_Name:");
var hbox_name = new Box (Orientation.HORIZONTAL, 20);
hbox_name.pack_start (label_name, false, true, 0);
hbox_name.pack_start (entry_name, true, true, 0);
entry_url = new Entry();
entry_url.set_icon_from_icon_name (Gtk.EntryIconPosition.SECONDARY, "edit-clear-symbolic");
entry_url.icon_press.connect ((pos, event) => {
if (pos == Gtk.EntryIconPosition.SECONDARY) {
entry_url.set_text("");// URL
}
});
var label_url = new Label.with_mnemonic ("_URL:");
var hbox_url = new Box (Orientation.HORIZONTAL, 20);
hbox_url.pack_start (label_url, false, true, 0);
hbox_url.pack_start (entry_url, true, true, 0);
var button_ok = new Button.with_label("OK");
button_ok.clicked.connect(on_ok_clicked);
vbox_edit_page = new Box(Orientation.VERTICAL,20);
vbox_edit_page.pack_start(hbox_name,false,true,0);
vbox_edit_page.pack_start(hbox_url,false,true,0);
vbox_edit_page.pack_start(button_ok,false,true,0);
stack.add(vbox_edit_page);
stack.visible_child = vbox_player_page;//
GUI . player,
c . . .
player = ElementFactory.make ("playbin", "play");//
directory_path = Environment.get_home_dir()+"/.stations_for_radio_app";
GLib.File file = GLib.File.new_for_path(directory_path);
if(!file.query_exists()){
try{
file.make_directory();//
}catch(Error e){
stderr.printf ("Error: %s\n", e.message);
}
create_default_stations();//
}
show_stations();//
}
create_default_stations.
. , URL. . – , – URL.
private void create_default_stations(){
string[] name_station = {"NonStopPlay","Classical Music","Fip Radio","Jazz Legends","Joy Radio","Live-icy","Music Radio","Radio Electron","Dubstep","Trancemission"};
string[] url_station = {"http://stream.nonstopplay.co.uk/nsp-128k-mp3","http://stream.srg-ssr.ch/m/rsc_de/mp3_128","http://direct.fipradio.fr/live/fip-midfi.mp3","http://jazz128legends.streamr.ru/","http://airtime.joyradio.cc:8000/airtime_192.mp3","http://live-icy.gss.dr.dk:8000/A/A05H.mp3","http://ice-the.musicradio.com/CapitalXTRANationalMP3","http://radio-electron.ru:8000/128","http://air.radiorecord.ru:8102/dub_320","http://air.radiorecord.ru:8102/tm_320"};
for(int i=0;i<10;i++){
try {
FileUtils.set_contents (directory_path+"/"+name_station[i], url_station[i]);
} catch (Error e) {
stderr.printf ("Error: %s\n", e.message);
}
}
}
show_stations:
private void show_stations () {
list_store.clear();
list = new GLib.List<string> ();
try {
Dir dir = Dir.open (directory_path, 0);
string? name = null;
while ((name = dir.read_name ()) != null) {
list.append(name);
}
} catch (FileError err) {
stderr.printf (err.message);
}
TreeIter iter;
foreach (string item in list) {
list_store.append(out iter);
list_store.set(iter, Columns.TEXT, item);//
}
}
/
alert.
:
private void alert (string str){
var dialog_alert = new Gtk.MessageDialog(this, Gtk.DialogFlags.MODAL, Gtk.MessageType.INFO, Gtk.ButtonsType.OK, str);
dialog_alert.set_title("Message");
dialog_alert.run();
dialog_alert.destroy();
}
:
private void on_play_station(){ //
var selection = tree_view.get_selection();
selection.set_mode(SelectionMode.SINGLE);
TreeModel model;
TreeIter iter;
if (!selection.get_selected(out model, out iter)) {
alert("Choose a station");
return;
}
string uri;
try {
FileUtils.get_contents (directory_path+"/"+item, out uri);
} catch (Error e) {
stderr.printf ("Error: %s\n", e.message);
}
player.uri = uri;
player.set_state (State.PLAYING);
set_widget_visible(play_button,false);
set_widget_visible(stop_button,true);
}
private void on_stop_station(){//
player.set_state (State.READY);
set_widget_visible(play_button,true);
set_widget_visible(stop_button,false);
}
:
private void on_add_clicked () {//
stack.visible_child = vbox_edit_page;
set_buttons_on_edit_page();
mode = 1;
if(!is_empty(entry_name.get_text())){
entry_name.set_text("");
}
if(!is_empty(entry_url.get_text())){
entry_url.set_text("");
}
}
private void on_edit_clicked(){//
var selection = tree_view.get_selection();
selection.set_mode(SelectionMode.SINGLE);
TreeModel model;
TreeIter iter;
if (!selection.get_selected(out model, out iter)) {
alert("Choose a station");
return;
}
stack.visible_child = vbox_edit_page;
set_buttons_on_edit_page();
mode = 0;
entry_name.set_text(item);//
string url;
try {
FileUtils.get_contents (directory_path+"/"+item, out url);
} catch (Error e) {
stderr.printf ("Error: %s\n", e.message);
}
entry_url.set_text(url);// URL
}
. mode
. : . .
private void on_ok_clicked(){
if(is_empty(entry_name.get_text())){
alert("Enter the name");
entry_name.grab_focus();
return;
}
if(is_empty(entry_url.get_text())){
alert("Enter the url");
entry_url.grab_focus();
return;
}
switch(mode){//
case 0://
GLib.File select_file = GLib.File.new_for_path(directory_path+"/"+item);
GLib.File edit_file = GLib.File.new_for_path(directory_path+"/"+entry_name.get_text().strip());
if (select_file.get_basename() != edit_file.get_basename() && !edit_file.query_exists()){
FileUtils.rename(select_file.get_path(), edit_file.get_path());
if(!edit_file.query_exists()){
alert("Rename failed");
return;
}
try {
FileUtils.set_contents (edit_file.get_path(), entry_url.get_text().strip());
} catch (Error e) {
stderr.printf ("Error: %s\n", e.message);
}
}else{
if (select_file.get_basename() != edit_file.get_basename()) {
alert("A station with the same name already exists");
entry_name.grab_focus();
return;
}
try {
FileUtils.set_contents (edit_file.get_path(), entry_url.get_text().strip());
} catch (Error e) {
stderr.printf ("Error: %s\n", e.message);
}
}
show_stations();
break;
case 1://
GLib.File file = GLib.File.new_for_path(directory_path+"/"+entry_name.get_text().strip());
if(file.query_exists()){
alert("A station with the same name already exists");
entry_name.grab_focus();
return;
}
try {
FileUtils.set_contents (file.get_path(), entry_url.get_text().strip());
} catch (Error e) {
stderr.printf ("Error: %s\n", e.message);
}
if(!file.query_exists()){
alert("Add failed");
return;
}else{
show_stations();
}
break;
}
on_back_clicked();
}
:
private void on_delete_dialog(){
var selection = tree_view.get_selection();
selection.set_mode(SelectionMode.SINGLE);
TreeModel model;
TreeIter iter;
if (!selection.get_selected(out model, out iter)) {
alert("Choose a station");
return;
}
GLib.File file = GLib.File.new_for_path(directory_path+"/"+item);
var dialog_delete_station = new Gtk.MessageDialog(this, Gtk.DialogFlags.MODAL,Gtk.MessageType.QUESTION, Gtk.ButtonsType.OK_CANCEL, "Delete station "+file.get_basename()+" ?");
dialog_delete_station.set_title("Question");
Gtk.ResponseType result = (ResponseType)dialog_delete_station.run ();
dialog_delete_station.destroy();
if(result==Gtk.ResponseType.OK){
FileUtils.remove (directory_path+"/"+item);
if(file.query_exists()){
alert("Delete failed");
}else{
show_stations();//
}
}
}
:
private void set_buttons_on_player_page(){//
set_widget_visible(back_button,false);
set_widget_visible(add_button,true);
set_widget_visible(delete_button,true);
set_widget_visible(edit_button,true);
}
private void set_buttons_on_edit_page(){// /
set_widget_visible(back_button,true);
set_widget_visible(add_button,false);
set_widget_visible(delete_button,false);
set_widget_visible(edit_button,false);
}
item
. , - :
private void on_select_item () {
var selection = tree_view.get_selection();
selection.set_mode(SelectionMode.SINGLE);
TreeModel model;
TreeIter iter;
if (!selection.get_selected(out model, out iter)) {
return;
}
TreePath path = model.get_path(iter);
var index = int.parse(path.to_string());
if (index >= 0) {
item = list.nth_data(index);//
}
}
:
private void on_back_clicked(){
stack.visible_child = vbox_player_page;
set_buttons_on_player_page();
}
is_empty:
private bool is_empty(string str){
return str.strip().length == 0;
}
:
private enum Columns {
TEXT, N_COLUMNS
}
:
valac --pkg gtk+-3.0 --pkg gstreamer-1.0 Application.vala MainWindow.vala
:
./Application
→ GitHub
! , .