[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