~elementary-apps/pantheon-terminal/master

« back to all changes in this revision

Viewing changes to main.vala

  • Committer: kekun.plazas@laposte.net
  • Date: 2011-06-19 15:34:04 UTC
  • Revision ID: git-v1:03007337b8d45983a3be21b8d295b5af68a60b04
CMake port in progress

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//  
2
 
//  Copyright (C) 2011 Adrien Plazas
3
 
// 
4
 
//  This program is free software: you can redistribute it and/or modify
5
 
//  it under the terms of the GNU General Public License as published by
6
 
//  the Free Software Foundation, either version 3 of the License, or
7
 
//  (at your option) any later version.
8
 
//  
9
 
//  This program is distributed in the hope that it will be useful,
10
 
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 
//  GNU General Public License for more details.
13
 
// 
14
 
//  You should have received a copy of the GNU General Public License
15
 
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
 
// 
17
 
// 
18
 
//  Authors:
19
 
//      Adrien Plazas <kekun.plazas@laposte.net>
20
 
//  Artists:
21
 
//      Daniel Fore <???@gmail.com>
22
 
// 
23
 
 
24
 
/* Use system font
25
 
 * Set preferences via GSettings ?
26
 
 * Do not focus on buttons
27
 
 * Improve window resize (is it useful ?)
28
 
 * Add right click menu with: copy, paste, preferences?, about
29
 
 * Notify with system bubbles if the window is not focused (check FIXME)
30
 
 * Set Dan correctly as the artist
31
 
 */
32
 
 
33
 
using Gtk;
34
 
using Vte;
35
 
using Notify;
36
 
 
37
 
private class PantheonTerminal : Window
38
 
{
39
 
    Notebook notebook;
40
 
    Gdk.Color bgcolor;
41
 
    Gdk.Color fgcolor;
42
 
    
43
 
    Notify.Notification notification;
44
 
    
45
 
        private PantheonTerminal()
46
 
        {
47
 
        Gtk.Settings.get_default().gtk_application_prefer_dark_theme = true;
48
 
        set_title("Terminal");
49
 
        default_width = 640;
50
 
        default_height = 400;
51
 
        destroy.connect(close);
52
 
                
53
 
        notebook = new Notebook();
54
 
                var left_box = new HBox(false, 0);
55
 
        var right_box = new HBox(false, 0);
56
 
        left_box.show();
57
 
        right_box.show();
58
 
        notebook.set_action_widget(left_box, PackType.START);
59
 
        notebook.set_action_widget(right_box, PackType.END);
60
 
        notebook.set_scrollable(true);
61
 
        add(notebook);
62
 
        
63
 
        left_box.set_size_request(10, 0);
64
 
        
65
 
        // Set "New tab" button
66
 
        var add_button = new Button();
67
 
        add_button.set_image(new Image.from_stock(Stock.ADD, IconSize.MENU));
68
 
        add_button.show();
69
 
        add_button.set_relief(ReliefStyle.NONE);
70
 
        add_button.set_tooltip_text("Open a new tab");
71
 
        add_button.clicked.connect(new_tab);
72
 
        right_box.pack_start(add_button, false, false, 0);
73
 
                
74
 
        // Get the system's style
75
 
        realize();
76
 
        bgcolor = get_style().bg[StateType.NORMAL];
77
 
        fgcolor = get_style().fg[StateType.NORMAL];
78
 
                        
79
 
                // Try to set the icon FIXME
80
 
        Gdk.Pixbuf icon = new Gdk.Pixbuf(Gdk.Colorspace.RGB, true, 8, 1, 1);
81
 
        try { IconTheme.get_default().load_icon("terminal", 16, IconLookupFlags.FORCE_SVG); } catch (Error er) {}
82
 
                try { set_icon(icon); } catch(Error er) {}
83
 
        
84
 
                show_all();
85
 
        new_tab();
86
 
        }
87
 
    
88
 
    private void new_tab()
89
 
    {
90
 
        // Set up terminal
91
 
        var t = new TerminalWithNotification();
92
 
        t.fork_command(null,null,null,null, true, true,true);
93
 
        
94
 
        // Test the "task_over" signal
95
 
        t.task_over.connect(() => {stdout.printf("task_over\n");});
96
 
 
97
 
        t.show();
98
 
        
99
 
        // Create a new tab with the terminal
100
 
        var tab = new TabWithCloseButton("Terminal");
101
 
        notebook.insert_page(t, tab, notebook.get_current_page() + 1);
102
 
        notebook.next_page();
103
 
        notebook.set_tab_reorderable(t, true);
104
 
        
105
 
        // Set connections
106
 
        tab.clicked.connect(() => { notebook.remove(t); });
107
 
        t.window_title_changed.connect(() => { tab.set_text(t.get_window_title()); });
108
 
        notebook.switch_page.connect((page, page_num) => { if (notebook.page_num(t) == (int) page_num) tab.set_notification(false); });
109
 
        t.task_over.connect(() => {
110
 
            if (notebook.page_num(t) != notebook.get_current_page())
111
 
                tab.set_notification(true);
112
 
            if (is_focus) // Check if the window have the focus FIXME
113
 
                stdout.printf("focus\n");
114
 
            });
115
 
        
116
 
        // Set up style
117
 
        t.set_color_background(bgcolor);
118
 
        t.set_color_foreground(fgcolor);
119
 
    }
120
 
    
121
 
    private void close()
122
 
    {
123
 
        Gtk.main_quit();
124
 
    }
125
 
    
126
 
        private static void main(string[] args)
127
 
        {
128
 
                Gtk.init(ref args);
129
 
                new PantheonTerminal();
130
 
                Gtk.main();
131
 
        }
132
 
}
133
 
 
134
 
public class TerminalWithNotification : Terminal
135
 
{
136
 
    public signal void task_over();
137
 
    
138
 
    long last_row_count = 0;
139
 
    long last_column_count = 0;
140
 
    
141
 
    public TerminalWithNotification()
142
 
    {
143
 
        set_size_request(320, 200);
144
 
        window_title_changed.connect(check_for_notification);
145
 
    }
146
 
    
147
 
    private void check_for_notification()
148
 
    {
149
 
        /* Curently I use this trick to know if a task is over, the drawnback is
150
 
         * that when the window is resized and a notification should be received,
151
 
         * the user will not be notified.
152
 
         */
153
 
        if (get_row_count() == last_row_count && get_column_count() == last_column_count)
154
 
            task_over();
155
 
        last_row_count = get_row_count();
156
 
        last_column_count = get_column_count();
157
 
    }
158
 
}
159
 
 
160
 
public class TabWithCloseButton : HBox
161
 
{
162
 
    public signal void clicked();
163
 
    
164
 
    private Button button;
165
 
    private Label label;
166
 
    private string text;
167
 
    bool notification = false;
168
 
    
169
 
    public TabWithCloseButton(string text)
170
 
    {
171
 
        this.text = text;
172
 
        
173
 
        // Button
174
 
        button = new Button();
175
 
        button.set_image(new Image.from_stock(Stock.CLOSE, IconSize.MENU));
176
 
        button.show();
177
 
        button.set_relief(ReliefStyle.NONE);
178
 
        button.clicked.connect(() => { clicked(); });
179
 
        
180
 
        // Label
181
 
        label = new Label(text);
182
 
        label.show();
183
 
        
184
 
        // Pack the elements
185
 
        pack_start(button, false, true, 0);
186
 
        pack_end(label, true, true, 0);
187
 
        show();
188
 
    }
189
 
    
190
 
    public void set_notification(bool notification)
191
 
    {
192
 
        this.notification = notification;
193
 
        if (notification)
194
 
        { label.set_markup("<span color=\"#18a0c0\">"+text+"</span>"); }
195
 
        else
196
 
        { label.set_markup(text); }
197
 
    }
198
 
    
199
 
    public void set_text(string text)
200
 
    {
201
 
        this.text = text;
202
 
        set_notification(notification);
203
 
    }
204
 
}