[Sugar-devel] [PATCH Terminal] The same tabs as browse
Rafael Ortiz
rafael at activitycentral.com
Mon Jun 4 15:34:59 EDT 2012
On Sun, Jun 3, 2012 at 4:09 PM, S. Daniel Francis <francis at sugarlabs.org>wrote:
> Signed-off-by: Daniel Francis <francis at sugarlabs.org>
> Signed-off-by: Agustin Zubiaga <aguz at sugarlabs.org>
> ---
> icons/close-tab.svg | 27 ++++++++++
> terminal.py | 42 ++++++++++-----
> widgets.py | 150
> +++++++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 206 insertions(+), 13 deletions(-)
> create mode 100644 icons/close-tab.svg
> create mode 100644 widgets.py
>
> diff --git a/icons/close-tab.svg b/icons/close-tab.svg
> new file mode 100644
> index 0000000..782ad24
> --- /dev/null
> +++ b/icons/close-tab.svg
> @@ -0,0 +1,27 @@
> +<?xml version="1.0" encoding="UTF-8"?>
> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
> "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
> + <!ENTITY fill_color "#FFFFFF">
> + <!ENTITY stroke_color "#010101">
> +]>
> +<svg
> + xmlns="http://www.w3.org/2000/svg"
> + version="1.1"
> + width="22.16"
> + height="22.16"
> + viewBox="0 0 22.16 22.16"
> + id="browse-close-tab"
> + xml:space="preserve">
> + <g
> + transform="matrix(1.3,0,0,1.3,-3.2682282,-3.3351543)"
> + id="browse-dialog-cancel"
> +
> style="stroke:&fill_color;;stroke-width:2.69230771;stroke-miterlimit:4;stroke-dasharray:none">
> + <path
> + d="M 14.798121,7.2131543 6.9900671,15.021208"
> + id="path2986"
> +
> style="fill:none;stroke:&fill_color;;stroke-width:2.69230771;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
> />
> + <path
> + d="M 6.9900671,7.2131543 14.798121,15.021208"
> + id="path3756"
> +
> style="fill:none;stroke:&fill_color;;stroke-width:2.69230771;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
> />
> + </g>
> +</svg>
> diff --git a/terminal.py b/terminal.py
> index 0ba2871..6918e3f 100644
> --- a/terminal.py
> +++ b/terminal.py
> @@ -32,7 +32,6 @@ from gi.repository import Pango
> from sugar3.graphics.toolbutton import ToolButton
> from sugar3.graphics.toolbarbox import ToolbarBox
> from sugar3.graphics.toolbarbox import ToolbarButton
> -from sugar3.graphics.notebook import Notebook
>
> from sugar3.activity.widgets import EditToolbar
> from sugar3.activity.widgets import ActivityToolbarButton
> @@ -40,6 +39,9 @@ from sugar3.activity.widgets import StopButton
> from sugar3.activity import activity
> from sugar3 import env
>
> +from widgets import BrowserNotebook
> +from widgets import TabLabel
> +
> MASKED_ENVIRONMENT = [
> 'DBUS_SESSION_BUS_ADDRESS',
> 'PPID']
> @@ -118,7 +120,8 @@ class TerminalActivity(activity.Activity):
> toolbar_box.show()
> self._update_accelerators(toolbar_box)
>
> - self._notebook = Notebook()
> + self._notebook = BrowserNotebook()
> + self._notebook.connect("tab-added", self.__open_tab_cb)
> self._notebook.set_property("tab-pos", Gtk.PositionType.TOP)
> self._notebook.set_scrollable(True)
> self._notebook.show()
> @@ -248,17 +251,24 @@ class TerminalActivity(activity.Activity):
> index = self._create_tab(None)
> self._notebook.page = index
> if self._notebook.get_n_pages() == 2:
> + self._notebook.get_tab_label(self._notebook.get_nth_page(0
> + )).show_close_button()
> self._delete_tab_button.props.sensitive = True
> self._previous_tab_button.props.sensitive = True
> self._next_tab_button.props.sensitive = True
>
> - def __close_tab_cb(self, btn):
> - self._close_tab(self._notebook.props.page)
> + def __close_tab_cb(self, btn, child):
> + index = self._notebook.page_num(child)
> + self._close_tab(index)
> if self._notebook.get_n_pages() == 1:
> + self._notebook.get_tab_label(self._notebook.get_nth_page(0
> + )).hide_close_button()
> self._delete_tab_button.props.sensitive = False
> self._previous_tab_button.props.sensitive = False
> self._next_tab_button.props.sensitive = False
>
> + self._notebook.update_tab_sizes()
> +
> def __prev_tab_cb(self, btn):
> if self._notebook.props.page == 0:
> self._notebook.props.page = self._notebook.get_n_pages() - 1
> @@ -305,9 +315,8 @@ class TerminalActivity(activity.Activity):
> vt.connect("window-title-changed", self.__tab_title_changed_cb)
>
> # FIXME have to resend motion events to parent, see #1402
> - vt.connect('motion-notify-event', self.__motion_notify_cb)
> + #vt.connect('motion-notify-event', self.__motion_notify_cb)
>
> - #FIXME Drag and drop not working SL#3655
> #vt.drag_dest_set(Gtk.DestDefaults.MOTION | Gtk.DestDefaults.DROP,
> # [('text/plain', 0, 0), ('STRING', 0, 1)],
> # Gdk.DragAction.DEFAULT |
> @@ -318,25 +327,32 @@ class TerminalActivity(activity.Activity):
>
> vt.show()
>
> - label = Gtk.Label()
> -
> scrollbar = Gtk.VScrollbar.new(vt.get_vadjustment())
> - scrollbar.show()
>
> box = Gtk.HBox()
> box.pack_start(vt, True, True, 0)
> box.pack_start(scrollbar, False, True, 0)
>
> box.vt = vt
> - box.label = label
> + box.show()
> +
> + tablabel = TabLabel(box)
> + tablabel.connect('tab-close', self.__close_tab_cb)
> + tablabel.update_size(200)
> + box.label = tablabel
> +
> + index = self._notebook.append_page(box, tablabel)
> + tablabel.show_all()
>
> - index = self._notebook.append_page(box, label)
> + self._notebook.update_tab_sizes()
> self._notebook.show_all()
>
> # Uncomment this to only show the tab bar when there is at least
> # one tab. I think it's useful to always see it, since it displays
> # the 'window title'.
> # self._notebook.props.show_tabs = self._notebook.get_n_pages() >
> 1
> + tablabel.hide_close_button() if self._notebook.get_n_pages() == 1\
> + else None
>
> # Launch the default shell in the HOME directory.
> os.chdir(os.environ["HOME"])
> @@ -380,8 +396,8 @@ class TerminalActivity(activity.Activity):
>
> return index
>
> - def __motion_notify_cb(self, widget, event):
> - self.emit('motion-notify-event', event)
> +# def __motion_notify_cb(self, widget, event):
> +# self.emit('motion-notify-event', event)
>
> def __become_root_cb(self, button):
> vt =
> self._notebook.get_nth_page(self._notebook.get_current_page()).vt
> diff --git a/widgets.py b/widgets.py
> new file mode 100644
> index 0000000..94eff64
> --- /dev/null
> +++ b/widgets.py
> @@ -0,0 +1,150 @@
> +#!/usr/bin/env python
> +# -*- coding: utf-8 -*-
> +# Copyright (C) 2006, Red Hat, Inc.
> +# Copyright (C) 2011, One Laptop Per Child
> +# Copyright (C) 2009, Tomeu Vizoso, Simon Schampijer
> +#
> +# This program 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 2 of the License, or
> +# (at your option) any later version.
> +#,
> +# This program 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, write to the Free Software
> +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
> USA
> +
> +from gi.repository import GObject
> +from gi.repository import Gtk
> +from gi.repository import Pango
> +
> +from sugar3.graphics.icon import Icon
> +
> +
> +class TabAdd(Gtk.Button):
> + __gtype_name__ = 'BrowseTabAdd'
> +
> + __gsignals__ = {
> + 'tab-added': (GObject.SignalFlags.RUN_FIRST,
> + None,
> + ([])),
> + }
> +
> + def __init__(self):
> + GObject.GObject.__init__(self)
> +
> + add_tab_icon = Icon(icon_name='add')
> + self.props.relief = Gtk.ReliefStyle.NONE
> + self.props.focus_on_click = False
> + icon_box = Gtk.HBox()
> + icon_box.pack_start(add_tab_icon, True, False, 0)
> + self.add(icon_box)
> + self.connect('clicked', self.__button_clicked_cb)
> + self.set_name('browse-tab-add')
> + add_tab_icon.show()
> + icon_box.show()
> + self.show()
> +
> + def __button_clicked_cb(self, button):
> + self.emit('tab-added')
> +
> +
> +class BrowserNotebook(Gtk.Notebook):
> + __gtype_name__ = 'BrowseNotebook'
> +
> + __gsignals__ = {
> + 'tab-added': (GObject.SignalFlags.RUN_FIRST,
> + None,
> + ([])),
> + }
> +
> + """Handle an extra tab at the end with an Add Tab button."""
> +
> + def __init__(self):
> + GObject.GObject.__init__(self)
> +
> + self.first_expose = True
> + self.connect("draw", self._draw_cb)
> + self._tab_add = TabAdd()
> + self._tab_add.connect('tab-added', self.on_add_tab)
> + self.set_action_widget(self._tab_add, Gtk.PackType.END)
> + self._tab_add.show()
> +
> + def _draw_cb(self, widget, event):
> + if self.first_expose:
> + self.update_tab_sizes()
> + self.first_expose = False
> +
> + def on_add_tab(self, obj):
> + self.emit('tab-added')
> +
> + def update_tab_sizes(self):
> + n_pages = self.get_n_pages()
> + canvas_size = self.get_allocation()
> +
> + # FIXME
> + # overlap_size = self.style_get_property('tab-overlap') * n_pages
> - 1
> + overlap_size = 0
> + allowed_size = canvas_size.width - overlap_size
> +
> + tab_new_size = int(float(allowed_size) / (n_pages) -\
> + self._tab_add.get_allocation().width - 5)
> +
> + for page_idx in range(n_pages):
> + page = self.get_nth_page(page_idx)
> + label = self.get_tab_label(page)
> + label.update_size(tab_new_size)
> +
> +
> +class TabLabel(Gtk.HBox):
> + __gtype_name__ = 'BrowseTabLabel'
> +
> + __gsignals__ = {
> + 'tab-close': (GObject.SignalFlags.RUN_FIRST,
> + None,
> + ([GObject.TYPE_PYOBJECT])),
> + }
> +
> + def __init__(self, child):
> + GObject.GObject.__init__(self)
> +
> + self.child = child
> + self._label = Gtk.Label(label="")
> + self._label.set_ellipsize(Pango.EllipsizeMode.END)
> + self._label.set_alignment(0, 0.5)
> + self.pack_start(self._label, True, True, 0)
> + self._label.show()
> +
> + close_tab_icon = Icon(icon_name='close-tab')
> + button = Gtk.Button()
> + button.props.relief = Gtk.ReliefStyle.NONE
> + button.props.focus_on_click = False
> + icon_box = Gtk.HBox()
> + icon_box.pack_start(close_tab_icon, True, False, 0)
> + button.add(icon_box)
> + button.connect('clicked', self.__button_clicked_cb)
> + button.set_name('browse-tab-close')
> + self.pack_start(button, False, True, 0)
> + close_tab_icon.show()
> + icon_box.show()
> + button.show()
> + self._close_button = button
> +
> + def set_text(self, title):
> + self._label.set_text(title)
> +
> + def update_size(self, size):
> + self.set_size_request(size, -1)
> +
> + def hide_close_button(self):
> + self._close_button.hide()
> +
> + def show_close_button(self):
> + self._close_button.show()
> +
> + def __button_clicked_cb(self, button):
> + self.emit('tab-close', self.child)
> --
> 1.7.10.2
>
Daniel committed it as:
http://git.sugarlabs.org/terminal/mainline/commit/2a3addb355c60e98dd714e8216a77f07a6f38d9a
Cheers.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.sugarlabs.org/archive/sugar-devel/attachments/20120604/8fa6fdc0/attachment-0001.html>
More information about the Sugar-devel
mailing list