summaryrefslogtreecommitdiff
path: root/src/inlinebox.h
blob: 24c11d3b0bbc9691af8f64d57b508b218c6d7540 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/* WWWLite, a lightweight web browser.
   Copyright (C) 2019 defanor

   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 <https://www.gnu.org/licenses/>.
*/

#ifndef INLINE_BOX_H
#define INLINE_BOX_H

#include <glib-object.h>
#include <gtk/gtk.h>

G_BEGIN_DECLS


/* inline box text */

/* Using just a GObject for it (and not a GtkWidget), since it's a few
   times slower with GtkWidget. */

#define IB_TEXT_TYPE (ib_text_get_type())
G_DECLARE_FINAL_TYPE (IBText, ib_text, IB, TEXT, GObject);

struct _IBText {
  GObject parent_instance;
  PangoLayout *layout;
  GtkAllocation alloc;
};

#define IS_IB_TEXT(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), IB_TEXT_TYPE))

IBText* ib_text_new (PangoLayout *layout);
gboolean ib_text_at_point(IBText *ibt, gint x, gint y, gint *position);


/* line break */

#define IB_BREAK_TYPE (ib_break_get_type())
G_DECLARE_FINAL_TYPE (IBBreak, ib_break, IB, BREAK, GObject);

struct _IBBreak
{
  GObject parent_instance;
};

#define IS_IB_BREAK(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), IB_BREAK_TYPE))
IBBreak *ib_break_new ();



/* link */

#define IB_LINK_TYPE (ib_link_get_type())
G_DECLARE_FINAL_TYPE (IBLink, ib_link, IB, LINK, GObject);

struct _IBLink
{
  GObject parent_instance;
  guint start;
  guint end;
  GList *objects;               /* todo */
  gchar *url;
};

#define IS_IB_LINK(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), IB_LINK_TYPE))
IBLink *ib_link_new (const gchar *url);


/* inline box */

#define INLINE_BOX_TYPE            (inline_box_get_type())
#define INLINE_BOX(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), INLINE_BOX_TYPE, InlineBox))
#define INLINE_BOX_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), INLINE_BOX_TYPE, InlineBoxClass))
#define IS_INLINE_BOX(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), INLINE_BOX_TYPE))
#define IS_INLINE_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), INLINE_BOX_TYPE))

typedef struct _InlineBox InlineBox;
typedef struct _InlineBoxClass InlineBoxClass;

struct _InlineBox
{
  GtkContainer parent_instance;
  GList *children;
  GList *last_child;
  /* It would be cleaner to store links as children, but that would
     require additional functions to manage children. Keeping a
     separate list for now; probably it's not worth the complication,
     and it's only needed to manage/draw focus. */
  GList *links;
  GObject *focused_object;
  guint selection_start;
  guint selection_end;
  guint match_start;
  guint match_end;
  gboolean wrap;
};

struct _InlineBoxClass
{
  GtkContainerClass parent_class;
};

GType inline_box_get_type (void) G_GNUC_CONST;
InlineBox *inline_box_new (void);
void inline_box_add_text (InlineBox *container, IBText *text);
void inline_box_break (InlineBox *container);
gchar *inline_box_get_text (InlineBox *ib);
gint inline_box_search (InlineBox *ib, guint start, gint end, const gchar *str);

G_END_DECLS

#endif