Skip to content

Commit

Permalink
Implement path bar
Browse files Browse the repository at this point in the history
  • Loading branch information
kra-mo committed Dec 22, 2023
1 parent 59883e1 commit 2586640
Show file tree
Hide file tree
Showing 14 changed files with 460 additions and 85 deletions.
15 changes: 15 additions & 0 deletions hyperplane/gtk/path-bar.blp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using Gtk 4.0;

template $HypPathBar : ScrolledWindow {
vscrollbar-policy: never;
hscrollbar-policy: external;
overflow: hidden;
window-placement: bottom_right;
Box segments_box {}

styles [
"undershoot-start",
"undershoot-end",
"path-bar",
]
}
12 changes: 12 additions & 0 deletions hyperplane/gtk/path-segment.blp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using Gtk 4.0;
using Adw 1;

template $HypPathSegment : Revealer {
Button button {
Adw.ButtonContent button_content {}

styles [
"flat",
]
}
}
18 changes: 9 additions & 9 deletions hyperplane/gtk/style-dark.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
.thumbnail-picture {
filter: initial;
}

navigation-view > shadow {
background: radial-gradient(farthest-side at right, rgba(0,0,0,.15) 0%, rgba(0,0,0,0) 100%);
}

.blue-icon { color: @blue_1; }
.blue-background { background: alpha(@blue_5, 0.5); }
.blue-extension { background: @blue_1; color: @dark_5; }
Expand All @@ -24,12 +32,4 @@

.gray-icon { color: @light_3; }
.gray-background { background: alpha(@dark_2, 0.5); }
.gray-extension { background: @light_4; color: @dark_5; }

.thumbnail-picture {
filter: initial;
}

navigation-view > shadow {
background: radial-gradient(farthest-side at right, rgba(0,0,0,.15) 0%, rgba(0,0,0,0) 100%);
}
.gray-extension { background: @light_4; color: @dark_5; }
126 changes: 77 additions & 49 deletions hyperplane/gtk/style.css
Original file line number Diff line number Diff line change
@@ -1,51 +1,3 @@
.white-background { background: @light_1; }
.white-icon { color: @light_1; }

.dark-blue-background { background: @blue_5; }
.light-blue-background { background: @blue_3; }

.blue-background { background: alpha(@blue_1, 0.5); }
.blue-icon { color: @blue_5; }
.blue-icon-light-only { color: @blue_5; }
.blue-extension { background: @blue_5; color: @light_1; }
.blue-extension-thumb { background: @blue_5; color: @light_1; }

.green-background { background: alpha(@green_1, 0.5); }
.green-icon { color: @green_5; }
.green-icon-light-only { color: @green_5; }
.green-extension { background: @green_5; color: @light_1; }
.green-extension-thumb { background: @green_5; color: @light_1; }

.yellow-background { background: alpha(@yellow_1, 0.5); }
.yellow-icon { color: @yellow_5; }
.yellow-icon-light-only { color: @yellow_5; }
.yellow-extension { background: @yellow_5; color: @light_1; }
.yellow-extension-thumb { background: @yellow_5; color: @light_1; }

.orange-background { background: alpha(@orange_1, 0.5); }
.orange-icon { color: @orange_5; }
.orange-icon-light-only { color: @orange_5; }
.orange-extension { background: @orange_5; color: @light_1; }
.orange-extension-thumb { background: @orange_5; color: @light_1; }

.red-background { background: alpha(@red_1, 0.5); }
.red-icon { color: @red_5; }
.red-icon-light-only { color: @red_5; }
.red-extension { background: @red_5; color: @light_1; }
.red-extension-thumb { background: @red_5; color: @light_1; }

.purple-background { background: alpha(@purple_1, 0.5); }
.purple-icon { color: @purple_4; }
.purple-icon-light-only { color: @purple_4; }
.purple-extension { background: @purple_4; color: @light_1; }
.purple-extension-thumb { background: @purple_4; color: @light_1; }

.gray-background { background: alpha(@light_4, 0.5); }
.gray-icon { color: @dark_2; }
.gray-icon-light-only { color: @dark_2; }
.gray-extension { background: @dark_2; color: @light_1; }
.gray-extension-thumb { background: @dark_2; color: @light_1; }

.item-thumbnail {
border-radius: 9px;
}
Expand All @@ -63,6 +15,34 @@ rubberband {
border-radius: 6px;
}

/* Stolen from Nautilus with some modifications */
.path-bar {
background-color: alpha(currentColor, 0.1);
border-radius: 6px;
}
.path-bar > undershoot.left {
background: linear-gradient(to right, alpha(@headerbar_shade_color, 0.5) 6px, alpha(@headerbar_shade_color, 0) 32px);
border-left: solid 1px @borders;
}
.path-bar > undershoot.right {
background: linear-gradient(to left, alpha(@headerbar_shade_color, 0.5) 6px, alpha(@headerbar_shade_color, 0) 32px);
border-right: solid 1px @borders;
}
.path-bar > viewport > box > revealer > button {
padding: 2px 9px;
margin: 3px;
border-radius: 4px;
}

.inactive-segment {
opacity: 0.5;
transition-duration: 0.2s;
}

.inactive-segment:hover {
opacity: 1;
}

/* Darken thumbnails so pure white images don't look weird */
.thumbnail-picture {
filter: brightness(.97);
Expand Down Expand Up @@ -96,4 +76,52 @@ navigation-view > dimming {

navigation-view > shadow {
background: radial-gradient(farthest-side at right, rgba(0,0,0,.08) 0%, rgba(0,0,0,0) 100%);
}
}

.white-background { background: @light_1; }
.white-icon { color: @light_1; }

.dark-blue-background { background: @blue_5; }
.light-blue-background { background: @blue_3; }

.blue-background { background: alpha(@blue_1, 0.5); }
.blue-icon { color: @blue_5; }
.blue-icon-light-only { color: @blue_5; }
.blue-extension { background: @blue_5; color: @light_1; }
.blue-extension-thumb { background: @blue_5; color: @light_1; }

.green-background { background: alpha(@green_1, 0.5); }
.green-icon { color: @green_5; }
.green-icon-light-only { color: @green_5; }
.green-extension { background: @green_5; color: @light_1; }
.green-extension-thumb { background: @green_5; color: @light_1; }

.yellow-background { background: alpha(@yellow_1, 0.5); }
.yellow-icon { color: @yellow_5; }
.yellow-icon-light-only { color: @yellow_5; }
.yellow-extension { background: @yellow_5; color: @light_1; }
.yellow-extension-thumb { background: @yellow_5; color: @light_1; }

.orange-background { background: alpha(@orange_1, 0.5); }
.orange-icon { color: @orange_5; }
.orange-icon-light-only { color: @orange_5; }
.orange-extension { background: @orange_5; color: @light_1; }
.orange-extension-thumb { background: @orange_5; color: @light_1; }

.red-background { background: alpha(@red_1, 0.5); }
.red-icon { color: @red_5; }
.red-icon-light-only { color: @red_5; }
.red-extension { background: @red_5; color: @light_1; }
.red-extension-thumb { background: @red_5; color: @light_1; }

.purple-background { background: alpha(@purple_1, 0.5); }
.purple-icon { color: @purple_4; }
.purple-icon-light-only { color: @purple_4; }
.purple-extension { background: @purple_4; color: @light_1; }
.purple-extension-thumb { background: @purple_4; color: @light_1; }

.gray-background { background: alpha(@light_4, 0.5); }
.gray-icon { color: @dark_2; }
.gray-icon-light-only { color: @dark_2; }
.gray-extension { background: @dark_2; color: @light_1; }
.gray-extension-thumb { background: @dark_2; color: @light_1; }
8 changes: 4 additions & 4 deletions hyperplane/gtk/window.blp
Original file line number Diff line number Diff line change
Expand Up @@ -211,12 +211,12 @@ template $HypWindow : Adw.ApplicationWindow {
transition-type: crossfade;
transition-duration: 100;

Adw.WindowTitle window_title {
title: bind template.title;
Adw.Clamp path_bar_clamp {
$HypPathBar path_bar {}
}

Adw.Clamp path_bar_clamp {
Entry path_bar {
Adw.Clamp path_entry_clamp {
Entry path_entry {
hexpand: true;

ShortcutController {
Expand Down
2 changes: 2 additions & 0 deletions hyperplane/hyperplane.gresource.xml.in
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
<file preprocess="xml-stripblanks">gtk/help-overlay.ui</file>
<file preprocess="xml-stripblanks">gtk/item.ui</file>
<file preprocess="xml-stripblanks">gtk/items-page.ui</file>
<file preprocess="xml-stripblanks">gtk/path-bar.ui</file>
<file preprocess="xml-stripblanks">gtk/path-segment.ui</file>
<file preprocess="xml-stripblanks">gtk/preferences.ui</file>
<file preprocess="xml-stripblanks">gtk/tag-row.ui</file>
<file preprocess="xml-stripblanks">gtk/window.ui</file>
Expand Down
3 changes: 1 addition & 2 deletions hyperplane/items_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,7 @@ def __init__(
self,
gfile: Optional[Gio.File] = None,
tags: Optional[list[str]] = None,
**kwargs: Any,
) -> None:
**kwargs) -> None:
super().__init__(**kwargs)
self.gfile = gfile
self.tags = tags
Expand Down
4 changes: 4 additions & 0 deletions hyperplane/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ blueprints = custom_target('blueprints',
'gtk/help-overlay.blp',
'gtk/item.blp',
'gtk/items-page.blp',
'gtk/path-bar.blp',
'gtk/path-segment.blp',
'gtk/preferences.blp',
'gtk/tag-row.blp',
'gtk/window.blp',
Expand Down Expand Up @@ -50,6 +52,8 @@ hyperplane_sources = [
'items_page.py',
'main.py',
'navigation_bin.py',
'path_bar.py',
'path_segment.py',
'postmaster_general.py',
'preferences.py',
'properties.py',
Expand Down
2 changes: 1 addition & 1 deletion hyperplane/navigation_bin.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def __init__(
self,
initial_gfile: Optional[Gio.File] = None,
initial_tags: Optional[Iterable[str]] = None,
**kwargs: Any,
**kwargs,
) -> None:
super().__init__(**kwargs)
self.view = Adw.NavigationView()
Expand Down
129 changes: 129 additions & 0 deletions hyperplane/path_bar.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# path_bar.py
#
# Copyright 2023 kramo
#
# 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 3 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, see <http://www.gnu.org/licenses/>.
#
# SPDX-License-Identifier: GPL-3.0-or-later

"""The path bar in a HypWindow."""
from typing import Optional

from gi.repository import GLib, Gtk

from hyperplane import shared
from hyperplane.path_segment import HypPathSegment


@Gtk.Template(resource_path=shared.PREFIX + "/gtk/path-bar.ui")
class HypPathBar(Gtk.ScrolledWindow):
"""The path bar in a HypWindow."""

__gtype_name__ = "HypPathBar"

segments_box: Gtk.Box = Gtk.Template.Child()
segments: list
separators: dict
tags: bool # Whether the path bar represents tags or a file

def __init__(self, **kwargs) -> None:
super().__init__(**kwargs)
self.segments = []
self.separators = {}
self.tags = False

def __remove_child(self, parent: Gtk.Box, child: Gtk.Widget) -> None:
# This is so GTK doesn't freak out when the child isn't in the box anymore
if child.get_parent == parent:
parent.remove(child)

def remove(self, n: int) -> None:
"""Removes n number of segments form self."""
for _index in range(n):
child = self.segments.pop()
child.set_reveal_child(False)
GLib.timeout_add(
child.get_transition_duration(),
self.__remove_child,
self.segments_box,
child,
)

if not (sep := self.separators[child]):
return

sep.set_reveal_child(False)
GLib.timeout_add(
sep.get_transition_duration(),
self.__remove_child,
self.segments_box,
sep,
)
self.separators.pop(child)

if self.tags:
return

try:
self.segments[-1].remove_css_class("inactive-segment")
self.segments[-2].add_css_class("inactive-segment")
except IndexError:
return

def append(
self,
label: str,
icon_name: Optional[str] = None,
uri: Optional[str] = None,
tag: Optional[str] = None,
) -> None:
"""Appends a HypPathSegment with `label` to self."""
if self.segments:
# Add a separator only if there is more than one item
sep_label = Gtk.Label.new("+" if self.tags else "/")
sep_label.add_css_class("heading" if self.tags else "dim-label")

sep = Gtk.Revealer(
child=sep_label, transition_type=Gtk.RevealerTransitionType.SLIDE_RIGHT
)
self.segments_box.append(sep)
sep.set_reveal_child(True)
else:
sep = None

path_segment = HypPathSegment(label, icon_name, uri, tag)
self.segments_box.append(path_segment)

path_segment.set_transition_type(Gtk.RevealerTransitionType.SLIDE_RIGHT)
path_segment.set_reveal_child(True)

self.separators[path_segment] = sep
self.segments.append(path_segment)

if self.tags:
return

try:
self.segments[-1].remove_css_class("inactive-segment")
self.segments[-2].add_css_class("inactive-segment")
except IndexError:
return

def purge(self) -> None:
"""Removes all segments from self."""
while child := self.segments_box.get_first_child():
self.segments_box.remove(child)

self.segments = []
self.separators = {}
Loading

0 comments on commit 2586640

Please sign in to comment.