talkatu/talkatu
Clone
Summary
Browse
Changes
Graph
Set layout managers for our GtkWidget subclasses
gtk4
2022-02-01, Gary Kramlich
bfd93f3bfba1
Set layout managers for our GtkWidget subclasses
Also disable the GtkBuildable for TalkatuScrolledWindow for now.
Testing Done:
Ran and verified the size allocation runtime warnings were gone.
Reviewed at https://reviews.imfreedom.org/r/1276/
/*
* Talkatu - GTK widgets for chat applications
* Copyright (C) 2017-2021 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
"talkatu/talkatuhtmlpangorenderer.h"
typedef
void
(
*
TalkatuHtmlPangoRendererStartFunc
)(
TalkatuHtmlPangoRenderer
*
renderer
,
const
gchar
*
name
,
const
gchar
**
attribute_names
,
const
gchar
**
attribute_values
);
typedef
void
(
*
TalkatuHtmlPangoRendererFinishFunc
)(
TalkatuHtmlPangoRenderer
*
renderer
,
const
gchar
*
name
);
typedef
struct
{
TalkatuHtmlPangoRendererStartFunc
start
;
TalkatuHtmlPangoRendererFinishFunc
finish
;
const
gchar
*
alias
;
}
TalkatuHtmlPangoRendererElementFuncs
;
struct
_TalkatuHtmlPangoRenderer
{
TalkatuHtmlRenderer
parent
;
GString
*
str
;
GHashTable
*
lookup
;
};
G_DEFINE_TYPE
(
TalkatuHtmlPangoRenderer
,
talkatu_html_pango_renderer
,
TALKATU_TYPE_HTML_RENDERER
)
/******************************************************************************
* TalkatuHtmlPangoRenderer Element Functions
*****************************************************************************/
static
void
talkatu_html_pango_renderer_passthrough_start
(
TalkatuHtmlPangoRenderer
*
renderer
,
const
gchar
*
name
,
const
gchar
**
attribute_names
,
const
gchar
**
attribute_values
)
{
g_string_append_printf
(
renderer
->
str
,
"<%s>"
,
name
);
}
static
void
talkatu_html_pango_renderer_passthrough_finish
(
TalkatuHtmlPangoRenderer
*
renderer
,
const
gchar
*
name
)
{
g_string_append_printf
(
renderer
->
str
,
"</%s>"
,
name
);
}
static
void
talkatu_html_pango_renderer_code_start
(
TalkatuHtmlPangoRenderer
*
renderer
,
const
gchar
*
name
,
const
gchar
**
attribute_names
,
const
gchar
**
attribute_values
)
{
g_string_append
(
renderer
->
str
,
"<span font=
\"
monospace
\"
>"
);
}
static
void
talkatu_html_pango_renderer_link_start
(
TalkatuHtmlPangoRenderer
*
renderer
,
const
gchar
*
name
,
const
gchar
**
attribute_names
,
const
gchar
**
attribute_values
)
{
gint
i
=
0
;
g_string_append
(
renderer
->
str
,
"<a"
);
if
(
attribute_names
!=
NULL
)
{
for
(
i
=
0
;
attribute_names
[
i
]
!=
NULL
;
i
++
)
{
if
(
g_ascii_strcasecmp
(
attribute_names
[
i
],
"href"
)
==
0
)
{
g_string_append_printf
(
renderer
->
str
,
" href=
\"
%s
\"
"
,
attribute_values
[
i
]);
}
}
}
g_string_append
(
renderer
->
str
,
">"
);
}
static
void
talkatu_html_pango_renderer_font_start
(
TalkatuHtmlPangoRenderer
*
renderer
,
const
gchar
*
name
,
const
gchar
**
attribute_names
,
const
gchar
**
attribute_values
)
{
gint
i
=
0
;
g_string_append
(
renderer
->
str
,
"<span"
);
if
(
attribute_names
!=
NULL
)
{
for
(
i
=
0
;
attribute_names
[
i
]
!=
NULL
;
i
++
)
{
if
(
g_ascii_strcasecmp
(
attribute_names
[
i
],
"size"
)
==
0
)
{
g_string_append_printf
(
renderer
->
str
,
" font=
\"
%s
\"
"
,
attribute_values
[
i
]);
}
else
if
(
g_ascii_strcasecmp
(
attribute_names
[
i
],
"color"
)
==
0
)
{
g_string_append_printf
(
renderer
->
str
,
" foreground=
\"
%s
\"
"
,
attribute_values
[
i
]);
}
}
}
g_string_append
(
renderer
->
str
,
">"
);
}
/******************************************************************************
* TalkatuHtmlRendererElementFuncs API
*****************************************************************************/
TalkatuHtmlPangoRendererElementFuncs
*
talkatu_html_pango_renderer_element_funcs_new
(
TalkatuHtmlPangoRendererStartFunc
start
,
TalkatuHtmlPangoRendererFinishFunc
finish
,
const
gchar
*
alias
)
{
TalkatuHtmlPangoRendererElementFuncs
*
funcs
=
NULL
;
funcs
=
g_new
(
TalkatuHtmlPangoRendererElementFuncs
,
1
);
funcs
->
start
=
start
;
funcs
->
finish
=
finish
;
funcs
->
alias
=
alias
;
return
funcs
;
}
TalkatuHtmlPangoRendererElementFuncs
*
talkatu_html_pango_renderer_element_funcs_new_passthrough
(
const
gchar
*
alias
)
{
return
talkatu_html_pango_renderer_element_funcs_new
(
talkatu_html_pango_renderer_passthrough_start
,
talkatu_html_pango_renderer_passthrough_finish
,
alias
);
}
/******************************************************************************
* TalkatuHtmlRenderer Implementation
*****************************************************************************/
static
void
talkatu_html_pango_renderer_reset
(
TalkatuHtmlRenderer
*
renderer
)
{
TalkatuHtmlPangoRenderer
*
pr
=
TALKATU_HTML_PANGO_RENDERER
(
renderer
);
g_string_free
(
pr
->
str
,
TRUE
);
pr
->
str
=
g_string_new
(
""
);
}
static
void
talkatu_html_pango_renderer_element_start
(
TalkatuHtmlRenderer
*
renderer
,
const
gchar
*
name
,
const
gchar
**
attribute_names
,
const
gchar
**
attribute_values
)
{
TalkatuHtmlPangoRenderer
*
pr
=
TALKATU_HTML_PANGO_RENDERER
(
renderer
);
TalkatuHtmlPangoRendererElementFuncs
*
funcs
=
NULL
;
funcs
=
g_hash_table_lookup
(
pr
->
lookup
,
name
);
if
(
funcs
!=
NULL
&&
funcs
->
start
!=
NULL
)
{
const
gchar
*
real_name
=
(
funcs
->
alias
!=
NULL
)
?
funcs
->
alias
:
name
;
funcs
->
start
(
pr
,
real_name
,
attribute_names
,
attribute_values
);
}
}
static
void
talkatu_html_pango_renderer_element_finish
(
TalkatuHtmlRenderer
*
renderer
,
const
gchar
*
name
)
{
TalkatuHtmlPangoRenderer
*
pr
=
TALKATU_HTML_PANGO_RENDERER
(
renderer
);
TalkatuHtmlPangoRendererElementFuncs
*
funcs
=
NULL
;
funcs
=
g_hash_table_lookup
(
pr
->
lookup
,
name
);
if
(
funcs
!=
NULL
&&
funcs
->
finish
!=
NULL
)
{
const
gchar
*
real_name
=
(
funcs
->
alias
!=
NULL
)
?
funcs
->
alias
:
name
;
funcs
->
finish
(
pr
,
real_name
);
}
}
static
void
talkatu_html_pango_renderer_text
(
TalkatuHtmlRenderer
*
renderer
,
const
gchar
*
text
)
{
TalkatuHtmlPangoRenderer
*
pr
=
TALKATU_HTML_PANGO_RENDERER
(
renderer
);
g_string_append
(
pr
->
str
,
text
);
}
/******************************************************************************
* GObject Implementation
*****************************************************************************/
static
void
talkatu_html_pango_renderer_init
(
TalkatuHtmlPangoRenderer
*
renderer
)
{
TalkatuHtmlPangoRendererElementFuncs
*
funcs
=
NULL
;
renderer
->
str
=
g_string_new
(
""
);
renderer
->
lookup
=
g_hash_table_new_full
(
g_str_hash
,
g_str_equal
,
NULL
,
g_free
);
funcs
=
talkatu_html_pango_renderer_element_funcs_new
(
talkatu_html_pango_renderer_link_start
,
talkatu_html_pango_renderer_passthrough_finish
,
NULL
);
g_hash_table_insert
(
renderer
->
lookup
,
"a"
,
funcs
);
funcs
=
talkatu_html_pango_renderer_element_funcs_new_passthrough
(
NULL
);
g_hash_table_insert
(
renderer
->
lookup
,
"b"
,
funcs
);
funcs
=
talkatu_html_pango_renderer_element_funcs_new
(
talkatu_html_pango_renderer_code_start
,
talkatu_html_pango_renderer_passthrough_finish
,
"span"
);
g_hash_table_insert
(
renderer
->
lookup
,
"code"
,
funcs
);
funcs
=
talkatu_html_pango_renderer_element_funcs_new_passthrough
(
NULL
);
g_hash_table_insert
(
renderer
->
lookup
,
"i"
,
funcs
);
funcs
=
talkatu_html_pango_renderer_element_funcs_new
(
talkatu_html_pango_renderer_font_start
,
talkatu_html_pango_renderer_passthrough_finish
,
"span"
);
g_hash_table_insert
(
renderer
->
lookup
,
"font"
,
funcs
);
funcs
=
talkatu_html_pango_renderer_element_funcs_new_passthrough
(
NULL
);
g_hash_table_insert
(
renderer
->
lookup
,
"s"
,
funcs
);
funcs
=
talkatu_html_pango_renderer_element_funcs_new_passthrough
(
"s"
);
g_hash_table_insert
(
renderer
->
lookup
,
"strike"
,
funcs
);
funcs
=
talkatu_html_pango_renderer_element_funcs_new_passthrough
(
NULL
);
g_hash_table_insert
(
renderer
->
lookup
,
"sub"
,
funcs
);
funcs
=
talkatu_html_pango_renderer_element_funcs_new_passthrough
(
NULL
);
g_hash_table_insert
(
renderer
->
lookup
,
"sup"
,
funcs
);
funcs
=
talkatu_html_pango_renderer_element_funcs_new_passthrough
(
NULL
);
g_hash_table_insert
(
renderer
->
lookup
,
"tt"
,
funcs
);
funcs
=
talkatu_html_pango_renderer_element_funcs_new_passthrough
(
NULL
);
g_hash_table_insert
(
renderer
->
lookup
,
"u"
,
funcs
);
}
static
void
talkatu_html_pango_renderer_finalize
(
GObject
*
obj
)
{
TalkatuHtmlPangoRenderer
*
renderer
=
TALKATU_HTML_PANGO_RENDERER
(
obj
);
g_string_free
(
renderer
->
str
,
TRUE
);
g_hash_table_destroy
(
renderer
->
lookup
);
G_OBJECT_CLASS
(
talkatu_html_pango_renderer_parent_class
)
->
finalize
(
obj
);
}
static
void
talkatu_html_pango_renderer_class_init
(
TalkatuHtmlPangoRendererClass
*
klass
)
{
GObjectClass
*
obj_class
=
G_OBJECT_CLASS
(
klass
);
TalkatuHtmlRendererClass
*
renderer_class
=
TALKATU_HTML_RENDERER_CLASS
(
klass
);
obj_class
->
finalize
=
talkatu_html_pango_renderer_finalize
;
renderer_class
->
reset
=
talkatu_html_pango_renderer_reset
;
renderer_class
->
element_start
=
talkatu_html_pango_renderer_element_start
;
renderer_class
->
element_finish
=
talkatu_html_pango_renderer_element_finish
;
renderer_class
->
text
=
talkatu_html_pango_renderer_text
;
}
/******************************************************************************
* Public API
*****************************************************************************/
TalkatuHtmlRenderer
*
talkatu_html_pango_renderer_new
(
void
)
{
return
TALKATU_HTML_RENDERER
(
g_object_new
(
TALKATU_TYPE_HTML_PANGO_RENDERER
,
NULL
));
}
const
gchar
*
talkatu_html_pango_renderer_get_string
(
TalkatuHtmlPangoRenderer
*
renderer
)
{
g_return_val_if_fail
(
TALKATU_IS_HTML_PANGO_RENDERER
(
renderer
),
NULL
);
return
renderer
->
str
->
str
;
}