Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 27 additions & 5 deletions data/ui/widgets/status.ui
Original file line number Diff line number Diff line change
Expand Up @@ -296,11 +296,33 @@
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="TubaWidgetsMarkupView" id="content">
<property name="visible">True</property>
<property name="hexpand">False</property>
<property name="extract-last-tags">True</property>
</object>
<object class="GtkOverlay">
<child type="overlay">
<object class="GtkButton">
<property name="label">Show All</property>
<property name="halign">center</property>
<property name="valign">end</property>
<property name="visible" bind-source="fade_bin" bind-property="faded" bind-flags="sync-create" />
<signal name="clicked" handler="on_fade_reveal" swapped="no" />
<style>
<class name="pill" />
</style>
</object>
</child>
<property name="child">
<object class="TubaWidgetsFadeBin" id="fade_bin">
<property name="child">
<object class="TubaWidgetsMarkupView" id="content">
<property name="halign">center</property>
<property name="valign">center</property>
<property name="visible">True</property>
<property name="hexpand">False</property>
<property name="extract-last-tags">True</property>
</object>
</property>
</object>
</property>
</object>
</child>
</object>
</property>
Expand Down
150 changes: 150 additions & 0 deletions src/Widgets/FadeBin.vala
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
public class Tuba.Widgets.FadeBin : Gtk.Widget {
const int MAX_HEIGHT = 300;
const float FADE_HEIGHT = 125f;

private Gtk.Widget? _child = null;
public Gtk.Widget? child {
get { return _child; }
set {
if (_child != null) _child.unparent ();
_child = value;
_child.set_parent (this);
}
}

~FadeBin () {
if (this.child != null) this.child.unparent ();
}

public override Gtk.SizeRequestMode get_request_mode () {
if (this.child != null) return this.child.get_request_mode ();
return Gtk.SizeRequestMode.HEIGHT_FOR_WIDTH;
}

private bool _reveal = false;
public bool reveal {
get { return _reveal; }
set {
if (_reveal != value) {
_reveal = value;
this.queue_draw ();
this.queue_resize ();
}
}
}

private bool _should_fade = false;
private bool should_fade {
get { return _should_fade; }
set {
if (_should_fade != value) {
_should_fade = value;
this.notify_property ("faded");
}
}
}

public bool faded {
get {
return this.should_fade && !reveal;
}
}

const Gsk.ColorStop[] GRADIENT = {
{ 0f, { 0, 0, 0, 1f } },
{ 1f, { 0, 0, 0, 0f } },
};

public override void size_allocate (int width, int height, int baseline) {
if (this.child == null) {
base.size_allocate (width, height, baseline);
this.should_fade = false;
return;
}

this.child.allocate (width, height, baseline, null);
if (this.reveal) {
this.should_fade = false;
return;
}

this.should_fade = this.child.get_height () >= MAX_HEIGHT;
}

public override void measure (Gtk.Orientation orientation, int for_size, out int minimum, out int natural, out int minimum_baseline, out int natural_baseline) {
this.child.measure (
orientation,
for_size,
out minimum,
out natural,
out minimum_baseline,
out natural_baseline
);
if (this.reveal) return;

minimum = int.min (minimum, MAX_HEIGHT);
minimum_baseline = -1;
natural_baseline = -1;
if (orientation == Gtk.Orientation.VERTICAL) {
natural = MAX_HEIGHT;
}
}

public override void snapshot (Gtk.Snapshot snapshot) {
if (this.child == null || !this.faded) {
this.child.snapshot (snapshot);
return;
}

var height = this.get_height ();
if (height <= 0) {
this.child.snapshot (snapshot);
return;
}

Gtk.Snapshot child_snapshot = new Gtk.Snapshot ();
this.snapshot_child (this.child, child_snapshot);
var node = child_snapshot.to_node ();
if (node == null) {
this.child.snapshot (snapshot);
return;
}

var bounds = node.get_bounds ();
bounds.origin.y = 0;
bounds.origin.x = Math.floorf (bounds.origin.x);
bounds.size.width = Math.ceilf (bounds.size.width) + 1;
bounds.size.height = height;

snapshot.push_mask (Gsk.MaskMode.INVERTED_ALPHA);

var new_fade = height - FADE_HEIGHT;
snapshot.append_linear_gradient (
Graphene.Rect () {
origin = Graphene.Point () {
x = bounds.origin.x,
y = new_fade
},
size = Graphene.Size () {
width = bounds.size.width,
height = FADE_HEIGHT
}
},
Graphene.Point () {
x = 0,
y = height
},
Graphene.Point () {
x = 0,
y = new_fade
},
GRADIENT
);

snapshot.pop ();
snapshot.push_clip (bounds);
snapshot.append_node (node);
snapshot.pop ();
snapshot.pop ();
}
}
5 changes: 5 additions & 0 deletions src/Widgets/LabelWithWidgets.vala
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,11 @@ public class Tuba.Widgets.LabelWithWidgets : Gtk.Widget, Gtk.Buildable, Gtk.Acce
set { label.xalign = value; }
}

public float yalign {
get { return label.yalign; }
set { label.yalign = value; }
}

public bool selectable {
get { return label.selectable; }
set { label.selectable = value; }
Expand Down
1 change: 1 addition & 0 deletions src/Widgets/MarkupView.vala
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ public class Tuba.Widgets.MarkupView : Gtk.Box {
large_emojis = settings.enlarge_custom_emojis,
use_markup = true,
fix_overflow_hack = true,
yalign = 0f,
// focusable_label = true
};
if (instance_emojis != null) label.instance_emojis = instance_emojis;
Expand Down
5 changes: 5 additions & 0 deletions src/Widgets/RichLabel.vala
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ public class Tuba.Widgets.RichLabel : Adw.Bin {
set { widget.xalign = value; }
}

public float yalign {
get { return widget.yalign; }
set { widget.yalign = value; }
}

public bool smaller_emoji_pixel_size {
get { return widget.smaller_emoji_pixel_size; }
set { widget.smaller_emoji_pixel_size = value; }
Expand Down
7 changes: 7 additions & 0 deletions src/Widgets/Status.vala
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@
[GtkChild] protected unowned Gtk.Label spoiler_label_rev;
[GtkChild] protected unowned Gtk.Box spoiler_status_con;

[GtkChild] protected unowned Widgets.FadeBin fade_bin;

[GtkChild] public unowned Gtk.Stack filter_stack;
[GtkChild] protected unowned Gtk.Label filter_label;

Expand Down Expand Up @@ -155,6 +157,7 @@
typeof (Widgets.Avatar).ensure ();
typeof (Widgets.RichLabel).ensure ();
typeof (Widgets.MarkupView).ensure ();
typeof (Widgets.FadeBin).ensure ();
}

construct {
Expand Down Expand Up @@ -1192,6 +1195,10 @@
new Dialogs.Compose.reply (status.formal, on_reply);
}

[GtkCallback] public void on_fade_reveal () {
fade_bin.reveal = true;
}

[GtkCallback] public void toggle_spoiler () {
status.formal.tuba_spoiler_revealed = !status.formal.tuba_spoiler_revealed;
if (status.formal.tuba_spoiler_revealed) {
Expand Down
1 change: 1 addition & 0 deletions src/Widgets/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ sources += files(
'Emoji.vala',
'EmojiLabel.vala',
'EmojiReactionAccounts.vala',
'FadeBin.vala',
'FocusPicker.vala',
'FocusPicture.vala',
'HashtagBar.vala',
Expand Down