container.vala 4.7 KB
Newer Older
Sergio Costas's avatar
Sergio Costas committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
/*
 Copyright 2016 (C) Raster Software Vigo (Sergio Costas)

 This file is part of Terminus

 Terminus is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 3 of the License, or
 (at your option) any later version.

 Terminus is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>. */

using Vte;
using Gtk;
using GLib;

namespace Terminus {

25 26 27 28 29 30
	/**
	 * This is the terminal container. It can contain one terminal, or a Paned with
	 * two containers. It can be splited in two elements and reagruped in a single
	 * one.
	 */

Sergio Costas's avatar
Sergio Costas committed
31 32
	class Container : Gtk.Bin {

33 34
		public Terminus.Container? container1;
		public Terminus.Container? container2;
Sergio Costas's avatar
Sergio Costas committed
35 36 37 38 39
		public Terminus.Notetab? notetab;

		private Terminus.Terminal? terminal;
		private Terminus.PanedPercentage? paned;
		private Terminus.Container top_container;
40
		private Terminus.Base main_container;
Sergio Costas's avatar
Sergio Costas committed
41

42
		public signal void ended(Terminus.Container who);
Sergio Costas's avatar
Sergio Costas committed
43

44
		public Container(Terminus.Base main_container, Terminus.Terminal? terminal, Terminus.Container? top_container = null) {
Sergio Costas's avatar
Sergio Costas committed
45

46
			this.main_container = main_container;
Sergio Costas's avatar
Sergio Costas committed
47 48
			if (top_container == null) {
				this.top_container = this;
49
				this.notetab = new Terminus.Notetab(this.main_container,this);
Sergio Costas's avatar
Sergio Costas committed
50 51 52 53
			} else {
				this.top_container = top_container;
				this.notetab = null;
			}
54 55

			if (terminal == null) {
56
				this.terminal = new Terminus.Terminal(this.main_container,this.top_container);
57 58 59 60 61 62 63
			} else {
				this.terminal = terminal;
			}

			this.set_terminal_child();
		}

Sergio Costas's avatar
Sergio Costas committed
64 65 66 67 68 69 70
		public void set_tab_title(string title) {

			if (this.notetab != null) {
				this.notetab.change_title(title);
			}
		}

71 72 73 74 75 76 77 78 79 80 81
		public void set_terminal_child() {
			this.add(this.terminal);
			this.terminal.ended.connect(this.ended_cb);

			this.terminal.split_horizontal.connect(this.split_horizontal_cb);
			this.terminal.split_vertical.connect(this.split_vertical_cb);

			this.paned = null;
			this.container1 = null;
			this.container2 = null;
		}
Sergio Costas's avatar
Sergio Costas committed
82

83
		public Gtk.Widget? get_current_child() {
Sergio Costas's avatar
Sergio Costas committed
84

85 86 87 88 89 90
			if (this.terminal != null) {
				this.terminal.split_horizontal.disconnect(this.split_horizontal_cb);
				this.terminal.split_vertical.disconnect(this.split_vertical_cb);
				this.terminal.ended.disconnect(this.ended_cb);
				this.remove(this.terminal);
				return this.terminal;
Sergio Costas's avatar
Sergio Costas committed
91
			} else {
92 93 94 95
				this.container1.ended.disconnect(this.ended_child);
				this.container2.ended.disconnect(this.ended_child);
				this.remove(this.paned);
				return this.paned;
Sergio Costas's avatar
Sergio Costas committed
96 97 98
			}
		}

99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
		public void ended_cb() {
			this.ended(this);
		}

		public void split_horizontal_cb() {
			this.split(true);
		}

		public void split_vertical_cb() {
			this.split(false);
		}

		private void split(bool horizontal) {
			this.remove(terminal);
			this.terminal.split_horizontal.disconnect(this.split_horizontal_cb);
			this.terminal.split_vertical.disconnect(this.split_vertical_cb);
			this.terminal.ended.disconnect(this.ended_cb);
Sergio Costas's avatar
Sergio Costas committed
116

117
			this.paned = new Terminus.PanedPercentage( horizontal ? Gtk.Orientation.VERTICAL : Gtk.Orientation.HORIZONTAL, 0.5);
118 119
			this.container1 = new Terminus.Container(this.main_container,this.terminal, this.top_container);
			this.container2 = new Terminus.Container(this.main_container,null, this.top_container);
120 121 122 123 124 125
			this.container1.ended.connect(this.ended_child);
			this.container2.ended.connect(this.ended_child);
			this.paned.add1(this.container1);
			this.paned.add2(this.container2);
			this.add(this.paned);
			this.paned.show_all();
Sergio Costas's avatar
Sergio Costas committed
126
			this.terminal = null;
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
		}

		public void ended_child(Terminus.Container child) {

			Terminus.Container old_container;

			if (child == this.container1) {
				old_container = this.container2;
			} else {
				old_container = this.container1;
			}
			var new_child = old_container.get_current_child();
			this.paned.remove(this.container1);
			this.paned.remove(this.container2);
			this.container1.ended.disconnect(this.ended_child);
			this.container2.ended.disconnect(this.ended_child);
			this.remove(this.paned);
			if (new_child is Terminus.Terminal) {
				this.terminal = new_child as Terminus.Terminal;
				this.set_terminal_child();
			} else {
148
				this.paned = new_child as Terminus.PanedPercentage;
149 150 151 152 153 154
				this.container1 = old_container.container1;
				this.container2 = old_container.container2;
				this.container1.ended.connect(this.ended_child);
				this.container2.ended.connect(this.ended_child);
				this.add(this.paned);
				this.paned.show_all();
Sergio Costas's avatar
Sergio Costas committed
155 156 157 158
			}
		}
	}
}