talkatu/talkatu
Clone
Summary
Browse
Changes
Graph
Fix the input in the demo.
gtk4
2022-02-03, Gary Kramlich
1819a3f27516
Fix the input in the demo.
We had some over zealous can-focus's set to 0 which was the main issue. The
other stuff was just stuff to clean up I found along the way.
Testing Done:
Ran the demo verified I can input text. Sending is still broken but that's another matter entirely...
Reviewed at https://reviews.imfreedom.org/r/1283/
/*
* Talkatu - GTK widgets for chat applications
* Copyright (C) 2017-2020 Gary Kramlich <grim@reaperworld.com>
*
* This library 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 library 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 library; if not, see <https://www.gnu.org/licenses/>.
*/
#include
<gtk/gtk.h>
#include
<talkatu/talkatuscrolledwindow.h>
/**
* TalkatuScrolledWindow:
* This widget is a simple subclass of #GtkScrolledWindow that has helpers for
* keyboard navigation as well as the ability to automatically scroll to the
* bottom when new items are added if the widget was already scrolled all the
* way to the bottom.
*/
struct
_TalkatuScrolledWindow
{
GtkWidget
parent
;
GtkWidget
*
scrolled_window
;
GtkAdjustment
*
vadjustment
;
gboolean
auto_scroll
;
};
enum
{
PROP_0
,
PROP_CHILD
,
N_PROPERTIES
,
};
static
GParamSpec
*
properties
[
N_PROPERTIES
]
=
{
NULL
,
};
/******************************************************************************
* Callbacks
*****************************************************************************/
static
void
talkatu_scrolled_window_vadjustment_changed_cb
(
GtkAdjustment
*
adjustment
,
gpointer
data
)
{
TalkatuScrolledWindow
*
sw
=
TALKATU_SCROLLED_WINDOW
(
data
);
if
(
sw
->
auto_scroll
)
{
gdouble
upper
,
pagesize
;
upper
=
gtk_adjustment_get_upper
(
adjustment
);
pagesize
=
gtk_adjustment_get_page_size
(
adjustment
);
gtk_adjustment_set_value
(
adjustment
,
upper
-
pagesize
);
}
}
static
void
talkatu_scrolled_window_vadjustment_value_changed_cb
(
GtkAdjustment
*
adjustment
,
gpointer
data
)
{
TalkatuScrolledWindow
*
sw
=
TALKATU_SCROLLED_WINDOW
(
data
);
gdouble
current
,
upper
,
pagesize
;
current
=
gtk_adjustment_get_value
(
adjustment
);
upper
=
gtk_adjustment_get_upper
(
adjustment
);
pagesize
=
gtk_adjustment_get_page_size
(
adjustment
);
sw
->
auto_scroll
=
(
current
+
pagesize
>=
upper
);
}
/******************************************************************************
* GtkBuildable Implementation
*****************************************************************************/
static
GtkBuildableIface
*
parent_buildable_iface
=
NULL
;
static
void
talkatu_scrolled_window_build_add_child
(
GtkBuildable
*
buildable
,
GtkBuilder
*
builder
,
GObject
*
child
,
const
gchar
*
type
)
{
if
(
GTK_IS_WIDGET
(
child
))
{
talkatu_scrolled_window_set_child
(
TALKATU_SCROLLED_WINDOW
(
buildable
),
GTK_WIDGET
(
child
));
}
else
{
parent_buildable_iface
->
add_child
(
buildable
,
builder
,
child
,
type
);
}
}
static
void
talkatu_scrolled_window_buildable_init
(
GtkBuildableIface
*
iface
)
{
parent_buildable_iface
=
g_type_interface_peek_parent
(
iface
);
iface
->
add_child
=
talkatu_scrolled_window_build_add_child
;
}
/******************************************************************************
* GObject Implementation
*****************************************************************************/
G_DEFINE_TYPE
(
TalkatuScrolledWindow
,
talkatu_scrolled_window
,
GTK_TYPE_WIDGET
)
static
void
tatlkatu_scrolled_window_get_property
(
GObject
*
obj
,
guint
param_id
,
GValue
*
value
,
GParamSpec
*
pspec
)
{
TalkatuScrolledWindow
*
sw
=
TALKATU_SCROLLED_WINDOW
(
obj
);
switch
(
param_id
)
{
case
PROP_CHILD
:
g_value_set_object
(
value
,
talkatu_scrolled_window_get_child
(
sw
));
break
;
default
:
G_OBJECT_WARN_INVALID_PROPERTY_ID
(
obj
,
param_id
,
pspec
);
break
;
}
}
static
void
tatlkatu_scrolled_window_set_property
(
GObject
*
obj
,
guint
param_id
,
const
GValue
*
value
,
GParamSpec
*
pspec
)
{
TalkatuScrolledWindow
*
sw
=
TALKATU_SCROLLED_WINDOW
(
obj
);
switch
(
param_id
)
{
case
PROP_CHILD
:
talkatu_scrolled_window_set_child
(
sw
,
g_value_get_object
(
value
));
break
;
default
:
G_OBJECT_WARN_INVALID_PROPERTY_ID
(
obj
,
param_id
,
pspec
);
break
;
}
}
static
void
talkatu_scrolled_window_init
(
TalkatuScrolledWindow
*
sw
)
{
gtk_widget_init_template
(
GTK_WIDGET
(
sw
));
sw
->
auto_scroll
=
TRUE
;
}
static
void
talkatu_scrolled_window_class_init
(
TalkatuScrolledWindowClass
*
klass
)
{
GObjectClass
*
obj_class
=
G_OBJECT_CLASS
(
klass
);
GtkWidgetClass
*
widget_class
=
GTK_WIDGET_CLASS
(
klass
);
obj_class
->
get_property
=
tatlkatu_scrolled_window_get_property
;
obj_class
->
set_property
=
tatlkatu_scrolled_window_set_property
;
/**
* TalkatuScrolledWindow::child:
*
* The child widget that should be displayed.
*/
properties
[
PROP_CHILD
]
=
g_param_spec_object
(
"child"
,
"child"
,
"The child widget to display"
,
GTK_TYPE_WIDGET
,
G_PARAM_READWRITE
);
gtk_widget_class_set_layout_manager_type
(
widget_class
,
GTK_TYPE_BIN_LAYOUT
);
gtk_widget_class_set_template_from_resource
(
widget_class
,
"/org/imfreedom/keep/talkatu/talkatu/ui/scrolledwindow.ui"
);
gtk_widget_class_bind_template_child
(
widget_class
,
TalkatuScrolledWindow
,
scrolled_window
);
gtk_widget_class_bind_template_child
(
widget_class
,
TalkatuScrolledWindow
,
vadjustment
);
gtk_widget_class_bind_template_callback
(
widget_class
,
talkatu_scrolled_window_vadjustment_changed_cb
);
gtk_widget_class_bind_template_callback
(
widget_class
,
talkatu_scrolled_window_vadjustment_value_changed_cb
);
}
/******************************************************************************
* Public API
*****************************************************************************/
/**
* talkatu_scrolled_window_new:
*
* Creates a new #TalkatuScrolledWindow.
*
* Returns: (transfer full): The new #TalkatuScrolledWindow instance.
*/
GtkWidget
*
talkatu_scrolled_window_new
(
void
)
{
return
g_object_new
(
TALKATU_TYPE_SCROLLED_WINDOW
,
NULL
);
}
/**
* talkatu_scrolled_window_page_up:
* @sw: The #TalkatuScrolledWindow instance.
*
* Scrolls @sw up one page.
*/
void
talkatu_scrolled_window_page_up
(
TalkatuScrolledWindow
*
sw
)
{
gdouble
value
=
0.0
;
g_return_if_fail
(
TALKATU_IS_SCROLLED_WINDOW
(
sw
));
value
=
gtk_adjustment_get_value
(
sw
->
vadjustment
);
value
-=
gtk_adjustment_get_page_increment
(
sw
->
vadjustment
);
gtk_adjustment_set_value
(
sw
->
vadjustment
,
value
);
}
/**
* talkatu_scrolled_window_page_down:
* @sw: The #TalkatuScrolledWindow instance.
*
* Scrolls @sw down one page.
*/
void
talkatu_scrolled_window_page_down
(
TalkatuScrolledWindow
*
sw
)
{
gdouble
value
=
0.0
;
g_return_if_fail
(
TALKATU_IS_SCROLLED_WINDOW
(
sw
));
value
=
gtk_adjustment_get_value
(
sw
->
vadjustment
);
value
+=
gtk_adjustment_get_page_increment
(
sw
->
vadjustment
);
gtk_adjustment_set_value
(
sw
->
vadjustment
,
value
);
}
/**
* talkatu_scrolled_window_get_child:
* @sw: The scrolled window instance.
*
* Gets the child of @sw.
*
* Returns: (transfer none) (nullable): The child of @sw.
*/
GtkWidget
*
talkatu_scrolled_window_get_child
(
TalkatuScrolledWindow
*
sw
)
{
g_return_val_if_fail
(
TALKATU_IS_SCROLLED_WINDOW
(
sw
),
NULL
);
return
gtk_scrolled_window_get_child
(
GTK_SCROLLED_WINDOW
(
sw
->
scrolled_window
));
}
/**
* talkatu_scrolled_window_set_child:
* @sw: The scrolled window instance.
* @child: (nullable): The new child or NULL to unset.
*
* Sets the child of @sw to @child.
*/
void
talkatu_scrolled_window_set_child
(
TalkatuScrolledWindow
*
sw
,
GtkWidget
*
child
)
{
g_return_if_fail
(
TALKATU_IS_SCROLLED_WINDOW
(
sw
));
gtk_scrolled_window_set_child
(
GTK_SCROLLED_WINDOW
(
sw
->
scrolled_window
),
child
);
}