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 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
|
/*
* File: dw_aligned_page.c
*
* Copyright (C) 2002, 2003 Sebastian Geerken <S.Geerken@ping.de>
*
* 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 2 of the License, or
* (at your option) any later version.
*/
/*
* This is an abstract class for horizontical alignment of an vertical
* array of text blocks, e.g. list items (with list item markers of
* different width) and (in the future) table cells aligned at
* characters (e.g. decimal point/comma).
*
* The aligned text blocks are represented by instances of sub-classes
* of DwAlignedPage, which define a value used for alignment
* (e.g. list item marker width), and implement the following two
* methods:
*
* get_value: Returns the value independent of all other
* values.
*
* set_max_value: This method is called to set the actual value,
* calculated from the maximum of all values.
*/
#include "dw_aligned_page.h"
#include "list.h"
static void Dw_aligned_page_class_init (DwAlignedPageClass *klass);
static void Dw_aligned_page_init (DwAlignedPage *aligned_page);
static void Dw_aligned_page_destroy (GtkObject *object);
static gint32 Dw_aligned_page_real_get_value (DwAlignedPage *aligned_page);
static void Dw_aligned_page_real_set_max_value (DwAlignedPage *aligned_page,
gint32 max_value,
gint32 value);
static DwPageClass *parent_class;
/*
* Standard Gtk+ function.
*/
GtkType a_Dw_aligned_page_get_type (void)
{
static GtkType type = 0;
if (!type) {
GtkTypeInfo info = {
"DwAlignedPage",
sizeof (DwAlignedPage),
sizeof (DwAlignedPageClass),
(GtkClassInitFunc) Dw_aligned_page_class_init,
(GtkObjectInitFunc) Dw_aligned_page_init,
(GtkArgSetFunc) NULL,
(GtkArgGetFunc) NULL,
(GtkClassInitFunc) NULL
};
type = gtk_type_unique (DW_TYPE_PAGE, &info);
}
return type;
}
/*
* Standard Gtk+ function.
*/
static void Dw_aligned_page_class_init (DwAlignedPageClass *klass)
{
parent_class = gtk_type_class (DW_TYPE_PAGE);
GTK_OBJECT_CLASS(klass)->destroy = Dw_aligned_page_destroy;
klass->get_value = Dw_aligned_page_real_get_value;
klass->set_max_value = Dw_aligned_page_real_set_max_value;
}
/*
* Standard Gtk+ function.
*/
static void Dw_aligned_page_init (DwAlignedPage *aligned_page)
{
aligned_page->list = NULL;
}
/*
* Standard Gtk+ function.
*/
static void Dw_aligned_page_destroy (GtkObject *object)
{
DwAlignedPage *aligned_page = DW_ALIGNED_PAGE (object);
if (aligned_page->list) {
if (aligned_page->list->refcount == 1) {
/* This is the last page in the array, so the list is removed. */
g_free (aligned_page->list->pages);
g_free (aligned_page->list->values);
g_free (aligned_page->list);
} else {
/* Remove this page from the list. The values are simply set to
NULL and 0. */
aligned_page->list->pages[aligned_page->list_pos] = NULL;
aligned_page->list->values[aligned_page->list_pos] = 0;
aligned_page->list->refcount--;
}
}
GTK_OBJECT_CLASS(parent_class)->destroy (object);
}
/*
* This function should be called by the sub-class to define the
* relations between the aligned pages. ref_page is either NULL (this
* will create a new array), or one page in an other array.
*/
void p_Dw_aligned_page_set_ref_page (DwAlignedPage *aligned_page,
DwAlignedPage *ref_page)
{
DwAlignedPageList *list;
if (ref_page == NULL) {
list = g_new (DwAlignedPageList, 1);
list->num = 0;
list->refcount = 0;
list->pages = NULL;
list->values = NULL;
list->num_pages_max = 4;
list->num_values_max = 4;
list->max_value = 0;
} else
list = ref_page->list;
list->num++;
list->refcount++;
a_List_add (list->pages, list->num, list->num_pages_max);
list->pages[list->num - 1] = aligned_page;
a_List_add (list->values, list->num, list->num_values_max);
list->values[list->num - 1] = 0;
aligned_page->list = list;
aligned_page->list_pos = list->num - 1;
p_Dw_aligned_page_update_value (aligned_page);
}
/*
* This function should be called by the sub-class whenever the
* alignment value changes.
*/
void p_Dw_aligned_page_update_value (DwAlignedPage *aligned_page)
{
DwAlignedPageClass *klass;
int i;
if (aligned_page->list) {
klass = DW_ALIGNED_PAGE_CLASS (GTK_OBJECT(aligned_page)->klass);
aligned_page->list->values[aligned_page->list_pos] =
klass->get_value (aligned_page);
if (aligned_page->list->values[aligned_page->list_pos] >
aligned_page->list->max_value) {
/* New value greater than current maximum -> apply it to others. */
aligned_page->list->max_value =
aligned_page->list->values[aligned_page->list_pos];
for (i = 0; i < aligned_page->list->num; i++)
if (aligned_page->list->pages[i]) {
klass = DW_ALIGNED_PAGE_CLASS
(GTK_OBJECT(aligned_page->list->pages[i])->klass);
klass->set_max_value (aligned_page->list->pages[i],
aligned_page->list->max_value,
aligned_page->list->values[i]);
}
} else {
/* No change, apply old max_value only to this page. */
klass = DW_ALIGNED_PAGE_CLASS (GTK_OBJECT(aligned_page)->klass);
klass->set_max_value (aligned_page, aligned_page->list->max_value,
aligned_page->list->values
[aligned_page->list_pos]);
}
}
}
/*
* Standard implementation of DwAlignedPage::get_value.
*/
static gint32 Dw_aligned_page_real_get_value (DwAlignedPage *aligned_page)
{
g_warning ("DwAlignedPage::get_value not implemented for `%s'",
gtk_type_name (GTK_OBJECT_TYPE (aligned_page)));
return 0;
}
/*
* Standard implementation of DwAlignedPage::set_max_value.
*/
static void Dw_aligned_page_real_set_max_value (DwAlignedPage *aligned_page,
gint32 max_value,
gint32 value)
{
g_warning ("DwAlignedPage::set_max_value not implemented for `%s'",
gtk_type_name (GTK_OBJECT_TYPE (aligned_page)));
}
|