guake-guake/guake/split_utils.py
2021-09-13 14:43:47 +02:00

171 lines
6.0 KiB
Python

# -*- coding: utf-8; -*-
"""
Copyright (C) 2018 Mario Aichinger <aichingm@gmail.com>
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 Street, Fifth Floor,
Boston, MA 02110-1301 USA
"""
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
from guake.boxes import DualTerminalBox
from guake.boxes import RootTerminalBox
class FocusMover:
THRESHOLD = 10
BORDER_THICKNESS = 2
def __init__(self, window):
self.window = window
def move_right(self, terminal):
window_width, window_height = self.window.get_size()
tx, ty, tw, th = self.list_allocation(terminal)
if tx + tw == window_width:
return
search_x = tx + tw + FocusMover.THRESHOLD
search_y = ty + (th / 2) - FocusMover.BORDER_THICKNESS
for term in terminal.get_parent().get_root_box().iter_terminals():
sx, sy, sw, sh = self.list_allocation(term)
if sx <= search_x <= sx + sw and sy <= search_y <= sy + sh:
term.grab_focus()
def move_left(self, terminal):
window_width, window_height = self.window.get_size()
tx, ty, tw, th = self.list_allocation(terminal)
if tx == 0:
return
search_x = tx - FocusMover.THRESHOLD
search_y = ty + (th / 2) - FocusMover.BORDER_THICKNESS
for term in terminal.get_parent().get_root_box().iter_terminals():
sx, sy, sw, sh = self.list_allocation(term)
if sx <= search_x <= sx + sw and sy <= search_y <= sy + sh:
term.grab_focus()
def move_up(self, terminal):
window_width, window_height = self.window.get_size()
tx, ty, tw, th = self.list_allocation(terminal)
if ty == 0:
return
search_x = tx + (tw / 2) - FocusMover.BORDER_THICKNESS
search_y = ty - FocusMover.THRESHOLD
for term in terminal.get_parent().get_root_box().iter_terminals():
sx, sy, sw, sh = self.list_allocation(term)
if sx <= search_x <= sx + sw and sy <= search_y <= sy + sh:
term.grab_focus()
def move_down(self, terminal):
window_width, window_height = self.window.get_size()
tx, ty, tw, th = self.list_allocation(terminal)
if ty + th == window_height:
return
search_x = tx + (tw / 2) - FocusMover.BORDER_THICKNESS
search_y = ty + th + FocusMover.THRESHOLD
for term in terminal.get_parent().get_root_box().iter_terminals():
sx, sy, sw, sh = self.list_allocation(term)
if sx <= search_x <= sx + sw and sy <= search_y <= sy + sh:
term.grab_focus()
def list_allocation(self, terminal):
terminal_rect = terminal.get_parent().get_allocation()
x, y = terminal.get_parent().translate_coordinates(self.window, 0, 0)
return x, y, terminal_rect.width, terminal_rect.height
class SplitMover:
THRESHOLD = 35
STEP = 10
@classmethod
def move_up(cls, terminal):
box = terminal.get_parent()
while not isinstance(box, RootTerminalBox):
box = box.get_parent()
if (
isinstance(box, DualTerminalBox)
and box.get_orientation() == Gtk.Orientation.VERTICAL
):
_, __, p = cls.list_allocation(box)
if p - SplitMover.STEP > SplitMover.THRESHOLD:
box.set_position(p - SplitMover.STEP)
else:
box.set_position(SplitMover.THRESHOLD)
break
@classmethod
def move_down(cls, terminal):
box = terminal.get_parent()
while not isinstance(box, RootTerminalBox):
box = box.get_parent()
if (
isinstance(box, DualTerminalBox)
and box.get_orientation() == Gtk.Orientation.VERTICAL
):
_, y, p = cls.list_allocation(box)
if p + SplitMover.STEP < y - SplitMover.THRESHOLD:
box.set_position(p + SplitMover.STEP)
else:
box.set_position(y - SplitMover.THRESHOLD)
break
@classmethod
def move_right(cls, terminal):
box = terminal.get_parent()
while not isinstance(box, RootTerminalBox):
box = box.get_parent()
if (
isinstance(box, DualTerminalBox)
and box.get_orientation() == Gtk.Orientation.HORIZONTAL
):
x, _, p = cls.list_allocation(box)
if p + SplitMover.STEP < x - SplitMover.THRESHOLD:
box.set_position(p + SplitMover.STEP)
else:
box.set_position(x - SplitMover.THRESHOLD)
break
@classmethod
def move_left(cls, terminal):
box = terminal.get_parent()
while not isinstance(box, RootTerminalBox):
box = box.get_parent()
if (
isinstance(box, DualTerminalBox)
and box.get_orientation() == Gtk.Orientation.HORIZONTAL
):
_, __, p = cls.list_allocation(box)
if p - SplitMover.STEP > SplitMover.THRESHOLD:
box.set_position(p - SplitMover.STEP)
else:
box.set_position(SplitMover.THRESHOLD)
break
@classmethod
def list_allocation(cls, box):
box_rect = box.get_allocation()
return box_rect.width, box_rect.height, box.get_position()