00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <math.h>
00029 #include <stdio.h>
00030 #include <stdlib.h>
00031 #include <string.h>
00032 #include <gtk/gtk.h>
00033
00034 #include "erGtkPageBar.h"
00035 #include "erGtkDialogJumpToPage.h"
00036
00037
00038 #define PAGEBAR_DEFAULT_PAGE_COUNT 1
00039 #define PAGEBAR_DEFAULT_CURRENT_PAGE 1
00040
00041 #define PAGEBAR_INDICATOR_SPACE 2
00042 #define PAGEBAR_CPI_SPACE 2
00043 #define PAGEBAR_CPI_ADJACENT_SPACE 1
00044
00045 #define PAGEBAR_ADJACENT_PAGES_NUM 3
00046
00047 #define PAGEBAR_HORIZONTAL_LINE_WIDTH 2
00048 #define PAGEBAR_INDICATOR_LINE_WIDTH 1
00049 #define PAGEBAR_INDICATOR_LINE_HEIGHT 12
00050
00051 #define PAGEBAR_INDICATOR_COLOR 0xAAAAAA
00052 #define PAGEBAR_NEXT_PAGE_TEXT_COLOR 0x555555
00053 #define PAGEBAR_LAST_PAGE_TEXT_COLOR 0x555555
00054
00055 #define PAGEBAR_BOOKMARK_SENSOR_RANGE 5
00056
00057 #define PAGEBAR_HORIZONTAL_MARGIN 4
00058 #define PAGEBAR_VERTICAL_MARGIN 0
00059
00060 #define PAGEBAR_MAX_PAGES 1000000
00061
00062
00063 typedef enum
00064 {
00065 BITMAP_CPI = 0,
00066 BITMAP_CPI_BOOKMARK,
00067 BITMAP_PREV_CPI,
00068 BITMAP_PREV_CPI_BOOKMARK,
00069 BITMAP_SUCC_CPI,
00070 BITMAP_SUCC_CPI_BOOKMARK,
00071 BITMAP_BOOKMARK,
00072 BITMAP_COUNT
00073 } BitmapIndex;
00074
00075 static const char * BITMAP_PATHS[BITMAP_COUNT] =
00076 {
00077 DATADIR "/pagebar_pagefield_black.png",
00078 DATADIR "/pagebar_pagefield_black_bookmark.png",
00079 DATADIR "/pagebar_pagefield_grey.png",
00080 DATADIR "/pagebar_pagefield_grey_bookmark.png",
00081 DATADIR "/pagebar_pagefield_white.png",
00082 DATADIR "/pagebar_pagefield_white_bookmark.png",
00083 DATADIR "/pagebar_bookmark_black.png",
00084 };
00085
00086
00087 typedef enum
00088 {
00089 STATUS_NORMAL = 0,
00090 STATUS_DETAILS,
00091 STATUS_SHRINK
00092 } PagebarStatus;
00093
00094 struct _GtkPagebar
00095 {
00096 GtkDrawingArea drawing_area;
00097 GdkPixmap *pixmap;
00098 PangoLayout *pango_layout;
00099 GdkGC *own_gc;
00100
00101 unsigned int page_count;
00102 unsigned int current_page;
00103 unsigned int last_selected_page;
00104
00105 PagebarStatus status;
00106
00107 GdkRectangle cpi_area;
00108
00109
00110 GArray *bookmarks;
00111
00112 int pagebar_width;
00113 int pagebar_height;
00114
00115 int left_indicator_offset;
00116 int right_indicator_offset;
00117
00118 unsigned int max_detailed_items;
00119 };
00120
00121 struct _GtkPagebarClass
00122 {
00123 GtkDrawingAreaClass parent_class;
00124
00125
00126 void (*pagebar_page_selected) (GtkPagebar * pagebar, int page);
00127
00128 };
00129
00130 static GtkDrawingAreaClass *g_parent_class = NULL;
00131
00132 typedef struct
00133 {
00134 GdkPixbuf *bitmaps[BITMAP_COUNT];
00135
00136 int cpi_width;
00137 int cpi_height;
00138 int page_field_width;
00139 int page_field_height;
00140 int bookmark_icon_width;
00141 int bookmark_icon_height;
00142 } bitmap_data_t;
00143 static const bitmap_data_t g_bitmap_data;
00144
00145 enum
00146 {
00147
00148 PAGE_SELECTED,
00149 LAST_SIGNAL,
00150 };
00151
00152 static gint pagebar_signals[LAST_SIGNAL] = { 0 };
00153
00154
00155 static gboolean on_pagebar_exposed(GtkWidget *, GdkEventExpose *, gpointer);
00156 static gboolean on_pagebar_configured(GtkWidget *, GdkEventConfigure *, gpointer);
00157 static gboolean on_pagebar_button_press_event(GtkWidget *, GdkEventButton *, gpointer);
00158 static gboolean on_pagebar_button_release_event(GtkWidget *, GdkEventButton *, gpointer);
00159
00160
00161 static void gtk_pagebar_class_init(GtkPagebarClass * klass);
00162 static void gtk_pagebar_init(GtkPagebar * pagebar);
00163 static void gtk_pagebar_finalize(GObject *obj);
00164
00165
00166 static void pagebar_load_bitmaps(void);
00167
00168
00169 static int get_bookmark_idx(GtkPagebar * pagebar, const unsigned int page_number);
00170 static gboolean add_bookmark(GtkPagebar * pagebar, const unsigned int page_number);
00171 static gboolean remove_bookmark(GtkPagebar * pagebar, const unsigned int page_number);
00172
00173
00174 static void pagebar_calculate_cpi(GtkPagebar * pagebar);
00175 static void pagebar_calculate_cpi_overview(GtkPagebar * pagebar);
00176 static void pagebar_calculate_cpi_shrink(GtkPagebar * pagebar);
00177 static void pagebar_calculate_cpi_details(GtkPagebar * pagebar);
00178
00179
00180 static void gtk_pagebar_draw(GtkPagebar * pagebar);
00181 static void pagebar_draw_details(GtkPagebar * pagebar);
00182 static void pagebar_draw_overview(GtkPagebar * pagebar);
00183
00184 static void pagebar_draw_cpi_overview(GtkPagebar * pagebar);
00185 static void pagebar_draw_cpi_shrink(GtkPagebar * pagebar);
00186
00187 static void pagebar_draw_markers(GtkPagebar * pagebar,
00188 const int bitmap,
00189 GArray *data,
00190 const int adjacent_pages);
00191
00192
00193 static int pagebar_calibrate_x_of_marker(GtkPagebar * pagebar, const int origin_x,
00194 const int offset);
00195 static int pagebar_get_x_of_marker(GtkPagebar * pagebar, const int page_number,
00196 const int adjacent_pages);
00197
00198 static gboolean pagebar_hit_test_markers(GtkPagebar * pagebar,
00199 int click_x, int click_y);
00200 static void pagebar_hit_test_on_cpi_overview(GtkPagebar * pagebar,
00201 int click_x, int click_y,
00202 int pagebar_width, int pagebar_height);
00203 static void pagebar_hit_test_on_indicator_overview(GtkPagebar * pagebar,
00204 int click_x, int click_y,
00205 int pagebar_width, int pagebar_height);
00206 static void pagebar_hit_test_details(GtkPagebar * pagebar,
00207 int click_x, int click_y);
00208 static void pagebar_hit_test_shrink(GtkPagebar * pagebar,
00209 int click_x, int click_y,
00210 int pagebar_width, int pagebar_height);
00211 static void pagebar_transfer_position(const int x, const int y,
00212 int * click_x, int * click_y,
00213 gboolean widget_to_pagebar);
00214
00215 static int on_current_page_changed(GtkPagebar * pagebar);
00216
00217
00218 GType gtk_pagebar_get_type(void)
00219 {
00220 static GType pagebar_type = 0;
00221
00222 if (!pagebar_type)
00223 {
00224 static const GTypeInfo pagebar_info = {
00225 sizeof(GtkPagebarClass),
00226 NULL,
00227 NULL,
00228 (GClassInitFunc) gtk_pagebar_class_init,
00229 NULL,
00230 NULL,
00231 sizeof(GtkPagebar),
00232 0,
00233 (GInstanceInitFunc) gtk_pagebar_init,
00234 NULL
00235 };
00236
00237 pagebar_type =
00238 g_type_register_static(GTK_TYPE_DRAWING_AREA,
00239 "erGtkPagebar",
00240 &pagebar_info,
00241 (GTypeFlags)(0));
00242 }
00243
00244 return pagebar_type;
00245 }
00246
00247 void gtk_pagebar_class_init(GtkPagebarClass * klass)
00248 {
00249 GObjectClass *object_class = (GObjectClass *) klass;
00250
00251
00252 g_parent_class = g_type_class_peek_parent(klass);
00253
00254
00255 object_class->finalize = gtk_pagebar_finalize;
00256
00257
00258 pagebar_signals[PAGE_SELECTED] = g_signal_new("pagebar_page_selected",
00259 G_TYPE_FROM_CLASS(object_class),
00260 G_SIGNAL_RUN_LAST,
00261 G_STRUCT_OFFSET(GtkPagebarClass,
00262 pagebar_page_selected),
00263 NULL,
00264 NULL,
00265 gtk_marshal_VOID__INT,
00266 G_TYPE_NONE,
00267 1,
00268 G_TYPE_INT);
00269
00270
00271 pagebar_load_bitmaps();
00272 }
00273
00274
00275 void gtk_pagebar_init(GtkPagebar * pagebar)
00276 {
00277 gtk_widget_set_events(GTK_WIDGET(pagebar),
00278 GDK_EXPOSURE_MASK | GDK_LEAVE_NOTIFY_MASK |
00279 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
00280
00281 gtk_signal_connect(GTK_OBJECT(pagebar),
00282 "expose-event",
00283 GTK_SIGNAL_FUNC(on_pagebar_exposed),
00284 pagebar);
00285
00286 gtk_signal_connect(GTK_OBJECT(pagebar),
00287 "configure-event",
00288 GTK_SIGNAL_FUNC(on_pagebar_configured),
00289 pagebar);
00290
00291 g_signal_connect(G_OBJECT(pagebar),
00292 "button_press_event",
00293 G_CALLBACK(on_pagebar_button_press_event),
00294 pagebar);
00295
00296 g_signal_connect(G_OBJECT(pagebar),
00297 "button_release_event",
00298 G_CALLBACK(on_pagebar_button_release_event),
00299 pagebar);
00300
00301 gtk_widget_show(GTK_WIDGET(pagebar));
00302 }
00303
00304
00305 static void gtk_pagebar_finalize (GObject *obj)
00306 {
00307 g_return_if_fail( IS_GTK_PAGEBAR(obj) );
00308 GtkPagebar *pagebar = GTK_PAGEBAR(obj);
00309
00310
00311 gtk_pagebar_reset(pagebar);
00312
00313 if (pagebar->own_gc)
00314 {
00315 g_object_unref(pagebar->own_gc);
00316 pagebar->own_gc = NULL;
00317 }
00318 if (pagebar->pango_layout)
00319 {
00320 g_object_unref(pagebar->pango_layout);
00321 pagebar->pango_layout = NULL;
00322 }
00323 if (pagebar->pixmap)
00324 {
00325 g_object_unref(pagebar->pixmap);
00326 pagebar->pixmap = NULL;
00327 }
00328
00329
00330
00331
00332 ((GObjectClass*)g_parent_class)->finalize( obj );
00333 }
00334
00335
00336 GtkWidget *gtk_pagebar_new()
00337 {
00338 GtkPagebar *pagebar = 0;
00339 PangoFontDescription *fontdesc = 0;
00340
00341 pagebar = (GtkPagebar *) g_object_new(GTK_PAGEBAR_TYPE, NULL);
00342
00343 pagebar->bookmarks = NULL;
00344
00345
00346 gtk_pagebar_reset(pagebar);
00347
00348
00349
00350 pagebar->pango_layout =
00351 gtk_widget_create_pango_layout(GTK_WIDGET(pagebar),
00352 "X");
00353 fontdesc =
00354 pango_font_description_from_string("Bitstream Vera Sans Roman 7.2");
00355
00356 pango_layout_set_font_description(pagebar->pango_layout, fontdesc);
00357 pango_font_description_free(fontdesc);
00358
00359 pagebar->pixmap = NULL;
00360 pagebar->own_gc = NULL;
00361
00362 return GTK_WIDGET(pagebar);
00363 }
00364
00365
00366
00367
00368
00369 void pagebar_load_bitmaps(void)
00370 {
00371 bitmap_data_t *data = (bitmap_data_t*) &g_bitmap_data;
00372
00373 int i;
00374 GError *error = NULL;
00375 const gchar *filename = NULL;
00376
00377
00378 for(i = 0; i < BITMAP_COUNT; ++i)
00379 {
00380 if (data->bitmaps[i] == NULL)
00381 {
00382 filename = BITMAP_PATHS[i];
00383 data->bitmaps[i] = gdk_pixbuf_new_from_file(filename, &error);
00384 if (error)
00385 {
00386 g_error("Loading bitmap %s error (%s)\n", filename, error->message);
00387 g_error_free(error);
00388 }
00389 }
00390 }
00391
00392
00393 if (data->bitmaps[BITMAP_CPI])
00394 {
00395 data->cpi_width = gdk_pixbuf_get_width(data->bitmaps[BITMAP_CPI]);
00396 data->cpi_height = gdk_pixbuf_get_height(data->bitmaps[BITMAP_CPI]);
00397 }
00398 if (data->bitmaps[BITMAP_SUCC_CPI])
00399 {
00400 data->page_field_width = gdk_pixbuf_get_width(data->bitmaps[BITMAP_SUCC_CPI]);
00401 data->page_field_height = gdk_pixbuf_get_height(data->bitmaps[BITMAP_SUCC_CPI]);
00402 }
00403 if (data->bitmaps[BITMAP_BOOKMARK])
00404 {
00405 data->bookmark_icon_width = gdk_pixbuf_get_width(data->bitmaps[BITMAP_BOOKMARK]);
00406 data->bookmark_icon_height = gdk_pixbuf_get_height(data->bitmaps[BITMAP_BOOKMARK]);
00407 }
00408 }
00409
00410
00411
00412
00413 static gint compare_bookmark(gconstpointer a, gconstpointer b)
00414 {
00415 gint bm_a = *((gint*)(a));
00416 gint bm_b = *((gint*)(b));
00417 if (bm_a > bm_b)
00418 {
00419 return 1;
00420 }
00421 else if (bm_a == bm_b)
00422 {
00423 return 0;
00424 }
00425 return -1;
00426 }
00427
00428 int get_bookmark_idx(GtkPagebar * pagebar, const unsigned int page_number)
00429 {
00430 unsigned int i;
00431 for(i=0; i < pagebar->bookmarks->len; ++i)
00432 {
00433 if (g_array_index(pagebar->bookmarks, guint, i) == page_number)
00434 {
00435 return i;
00436 }
00437 }
00438
00439 return -1;
00440 }
00441
00442 gboolean add_bookmark(GtkPagebar * pagebar, const unsigned int page_number)
00443 {
00444 if (page_number <= 0 || page_number > pagebar->page_count)
00445 {
00446 return FALSE;
00447 }
00448
00449 if (pagebar->bookmarks == NULL)
00450 {
00451 pagebar->bookmarks = g_array_new(FALSE, FALSE, sizeof(unsigned int));
00452 }
00453
00454 if (get_bookmark_idx(pagebar, page_number) >= 0)
00455 {
00456
00457 return TRUE;
00458 }
00459
00460 g_array_append_val(pagebar->bookmarks, page_number);
00461
00462 g_array_sort (pagebar->bookmarks, compare_bookmark);
00463
00464 gtk_pagebar_draw(pagebar);
00465
00466 return TRUE;
00467 }
00468
00469
00470
00471
00472 gboolean remove_bookmark(GtkPagebar * pagebar, const unsigned int page_number)
00473 {
00474 if (pagebar->bookmarks == NULL)
00475 {
00476 return FALSE;
00477 }
00478 if (page_number <= 0 || page_number > pagebar->page_count)
00479 {
00480 return FALSE;
00481 }
00482
00483 int idx = get_bookmark_idx(pagebar, page_number);
00484 if (idx < 0)
00485 {
00486 return FALSE;
00487 }
00488
00489 pagebar->bookmarks = g_array_remove_index(pagebar->bookmarks, idx);
00490 gtk_pagebar_draw(pagebar);
00491
00492 return TRUE;
00493 }
00494
00495
00496
00497 gboolean on_pagebar_configured(GtkWidget * widget,
00498 GdkEventConfigure * event,
00499 gpointer user_data)
00500 {
00501 GtkPagebar *pagebar = GTK_PAGEBAR(user_data);
00502
00503 if (pagebar->own_gc)
00504 {
00505 g_object_unref(pagebar->own_gc);
00506 pagebar->own_gc = NULL;
00507 }
00508 if (pagebar->pixmap)
00509 {
00510 g_object_unref(pagebar->pixmap);
00511 pagebar->pixmap = NULL;
00512 }
00513
00514
00515 pagebar->pixmap = gdk_pixmap_new(widget->window,
00516 widget->allocation.width,
00517 widget->allocation.height,
00518 -1);
00519
00520 pagebar->own_gc = gdk_gc_new(pagebar->pixmap);
00521
00522 gdk_draw_rectangle(pagebar->pixmap,
00523 widget->style->white_gc,
00524 TRUE,
00525 0,
00526 0,
00527 widget->allocation.width,
00528 widget->allocation.height);
00529
00530
00531 pagebar->max_detailed_items = (widget->allocation.width - g_bitmap_data.cpi_width) /
00532 (g_bitmap_data.page_field_width + PAGEBAR_CPI_SPACE) + 1;
00533
00534 if (pagebar->page_count > pagebar->max_detailed_items)
00535 {
00536 pagebar->status = STATUS_NORMAL;
00537 int least_len = (g_bitmap_data.page_field_width << 1) +
00538 (g_bitmap_data.page_field_width + PAGEBAR_CPI_SPACE) * (PAGEBAR_ADJACENT_PAGES_NUM << 1) +
00539 (g_bitmap_data.cpi_width + PAGEBAR_CPI_SPACE);
00540
00541 if (widget->allocation.width < least_len)
00542 {
00543 pagebar->status = STATUS_SHRINK;
00544 }
00545 }
00546 else
00547 {
00548 pagebar->status = STATUS_DETAILS;
00549 }
00550
00551
00552 gdk_drawable_get_size(pagebar->pixmap, &pagebar->pagebar_width,
00553 &pagebar->pagebar_height);
00554 pagebar->pagebar_width -= (PAGEBAR_HORIZONTAL_MARGIN << 1);
00555 pagebar->pagebar_height -= (PAGEBAR_VERTICAL_MARGIN << 1);
00556
00557 gtk_pagebar_draw(pagebar);
00558
00559 return TRUE;
00560 }
00561
00562
00563 gboolean on_pagebar_exposed(GtkWidget * widget,
00564 GdkEventExpose * event,
00565 gpointer user_data)
00566 {
00567
00568 GtkPagebar *pagebar = GTK_PAGEBAR(user_data);
00569
00570 g_return_val_if_fail(IS_GTK_PAGEBAR(pagebar), FALSE);
00571
00572
00573 gdk_draw_drawable(widget->window,
00574 widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
00575 pagebar->pixmap,
00576 event->area.x, event->area.y,
00577 event->area.x, event->area.y,
00578 event->area.width, event->area.height);
00579
00580 return FALSE;
00581 }
00582
00583 void pagebar_transfer_position(const int x, const int y,
00584 int * click_x, int * click_y,
00585 gboolean widget_to_pagebar)
00586 {
00587 if (widget_to_pagebar)
00588 {
00589 *click_x = x - PAGEBAR_HORIZONTAL_MARGIN;
00590 *click_y = y - PAGEBAR_VERTICAL_MARGIN;
00591 }
00592 else
00593 {
00594
00595 *click_x = x + PAGEBAR_HORIZONTAL_MARGIN;
00596 *click_y = y + PAGEBAR_VERTICAL_MARGIN;
00597 }
00598 }
00599
00600 gboolean pagebar_hit_test_markers(GtkPagebar * pagebar,
00601 int click_x, int click_y)
00602 {
00603
00604 GArray *markers = pagebar->bookmarks;
00605 if (markers == NULL)
00606 {
00607 return FALSE;
00608 }
00609
00610 int dst_page = -1;
00611 unsigned int idx = 0;
00612 for (; idx < markers->len; idx++)
00613 {
00614
00615 int mark_page = g_array_index(markers, guint, idx);
00616 int marker_x = pagebar_get_x_of_marker(pagebar, mark_page, PAGEBAR_ADJACENT_PAGES_NUM);
00617 if (marker_x < 0)
00618 {
00619 continue;
00620 }
00621 if (click_x < (marker_x + PAGEBAR_BOOKMARK_SENSOR_RANGE +
00622 g_bitmap_data.bookmark_icon_width) &&
00623 click_x > (marker_x - PAGEBAR_BOOKMARK_SENSOR_RANGE))
00624 {
00625
00626 dst_page = mark_page;
00627 break;
00628 }
00629 }
00630
00631 if (dst_page > 0)
00632 {
00633 pagebar->current_page = dst_page;
00634 on_current_page_changed(pagebar);
00635 return TRUE;
00636 }
00637
00638 return FALSE;
00639 }
00640
00641 void pagebar_hit_test_on_cpi_overview(GtkPagebar * pagebar,
00642 int click_x, int click_y,
00643 int pagebar_width, int pagebar_height)
00644 {
00645
00646 int first_page = pagebar->current_page - PAGEBAR_ADJACENT_PAGES_NUM;
00647 if (first_page < 1)
00648 {
00649 first_page = 1;
00650 }
00651 unsigned int last_page = pagebar->current_page + PAGEBAR_ADJACENT_PAGES_NUM;
00652 if (last_page > pagebar->page_count)
00653 {
00654 last_page = pagebar->page_count;
00655 }
00656
00657 unsigned int idx = first_page;
00658 int cur_x = pagebar->cpi_area.x;
00659 int cur_width = g_bitmap_data.page_field_width;
00660 for (; idx <= last_page; ++idx)
00661 {
00662 if (idx == pagebar->current_page)
00663 {
00664 cur_width = g_bitmap_data.cpi_width + PAGEBAR_CPI_SPACE;
00665 }
00666 else if (idx == (pagebar->current_page - 1))
00667 {
00668 cur_width = g_bitmap_data.page_field_width + PAGEBAR_CPI_SPACE;
00669 }
00670 else
00671 {
00672 cur_width = g_bitmap_data.page_field_width + PAGEBAR_CPI_ADJACENT_SPACE;
00673 }
00674
00675 if (click_x >= cur_x && click_x <= cur_x + cur_width)
00676 {
00677
00678 if (idx == pagebar->current_page)
00679 {
00680
00681 GtkWidget* jump_to_page_dialog = ergtk_jump_to_page_dialog_new();
00682 int response = gtk_dialog_run(GTK_DIALOG(jump_to_page_dialog));
00683 gtk_widget_destroy(jump_to_page_dialog);
00684
00685 if (response > 0)
00686 {
00687 if (response <= (int) pagebar->page_count)
00688 {
00689 pagebar->current_page = response;
00690 }
00691 else
00692 {
00693 pagebar->current_page = pagebar->page_count;
00694 }
00695 }
00696 }
00697 else
00698 {
00699 pagebar->current_page = idx;
00700 }
00701 break;
00702 }
00703
00704 cur_x += cur_width;
00705 }
00706 on_current_page_changed(pagebar);
00707 }
00708
00709 void pagebar_hit_test_on_indicator_overview(GtkPagebar * pagebar,
00710 int click_x, int click_y,
00711 int pagebar_width, int pagebar_height)
00712 {
00713
00714 if (pagebar_hit_test_markers(pagebar, click_x, click_y))
00715 {
00716 return;
00717 }
00718
00719
00720 int left_len = 0, right_len = 0;
00721 if (pagebar->cpi_area.x > 0)
00722 {
00723 left_len = pagebar->cpi_area.x - g_bitmap_data.page_field_width;
00724 }
00725 int cpi_right = pagebar->cpi_area.x + pagebar->cpi_area.width;
00726 if (cpi_right < pagebar_width)
00727 {
00728 right_len = pagebar_width - g_bitmap_data.page_field_width - cpi_right;
00729 }
00730
00731
00732 int x = click_x;
00733 int first_page = 1;
00734 int pages_left = 0;
00735 int offset_page = 0;
00736
00737 if (x < pagebar->cpi_area.x)
00738 {
00739
00740 x -= g_bitmap_data.page_field_width;
00741 first_page = 1;
00742 pages_left = (pagebar->current_page - PAGEBAR_ADJACENT_PAGES_NUM) -
00743 first_page;
00744 offset_page = x * pages_left / left_len;
00745 }
00746 else
00747 {
00748 x -= cpi_right;
00749 first_page = pagebar->current_page + PAGEBAR_ADJACENT_PAGES_NUM;
00750 pages_left = (pagebar->page_count - 1) - first_page;
00751 offset_page = x * pages_left / right_len;
00752 }
00753
00754 if (offset_page <= 0)
00755 {
00756 offset_page = 1;
00757 }
00758 pagebar->current_page = first_page + offset_page;
00759
00760 on_current_page_changed(pagebar);
00761 }
00762
00763
00764 void pagebar_hit_test_details(GtkPagebar * pagebar,
00765 int click_x, int click_y)
00766 {
00767
00768
00769 unsigned int idx = 1;
00770 int cur_x = pagebar->cpi_area.x;
00771 int cur_width = g_bitmap_data.page_field_width;
00772 for (; idx <= pagebar->page_count; ++idx)
00773 {
00774 if (idx == pagebar->current_page)
00775 {
00776 cur_width = g_bitmap_data.cpi_width + PAGEBAR_CPI_SPACE;
00777 }
00778 else if (idx == (pagebar->current_page - 1))
00779 {
00780 cur_width = g_bitmap_data.page_field_width + PAGEBAR_CPI_SPACE;
00781 }
00782 else
00783 {
00784 cur_width = g_bitmap_data.page_field_width + PAGEBAR_CPI_ADJACENT_SPACE;
00785 }
00786
00787 if (click_x >= cur_x && click_x <= cur_x + cur_width)
00788 {
00789
00790 if (idx == pagebar->current_page)
00791 {
00792
00793 GtkWidget* jump_to_page_dialog = ergtk_jump_to_page_dialog_new();
00794 int response = gtk_dialog_run(GTK_DIALOG(jump_to_page_dialog));
00795 gtk_widget_destroy(jump_to_page_dialog);
00796
00797 if (response > 0)
00798 {
00799 if (response <= (int) pagebar->page_count)
00800 {
00801 pagebar->current_page = response;
00802 }
00803 else
00804 {
00805 pagebar->current_page = pagebar->page_count;
00806 }
00807 }
00808 }
00809 else
00810 {
00811 pagebar->current_page = idx;
00812 }
00813 break;
00814 }
00815
00816 cur_x += cur_width;
00817 }
00818 on_current_page_changed(pagebar);
00819 }
00820
00821 void pagebar_hit_test_shrink(GtkPagebar * pagebar,
00822 int click_x, int click_y,
00823 int pagebar_width, int pagebar_height)
00824 {
00825
00826 int x = click_x;
00827 if (x >= pagebar->cpi_area.x &&
00828 x <= pagebar->cpi_area.x + pagebar->cpi_area.width)
00829 {
00830
00831
00832 return;
00833 }
00834 else if (x >= 0 && x <= g_bitmap_data.page_field_width)
00835 {
00836 pagebar->current_page = 1;
00837 }
00838 else if (x <= pagebar_width && x >= pagebar_width - g_bitmap_data.page_field_width)
00839 {
00840 pagebar->current_page = pagebar->page_count;
00841 }
00842 else
00843 {
00844 if (pagebar_hit_test_markers(pagebar, click_x, click_y))
00845 {
00846
00847 return;
00848 }
00849
00850
00851 int overview_length = pagebar_width - pagebar->cpi_area.width;
00852 if (pagebar->current_page > 1 && pagebar->current_page < pagebar->page_count)
00853 {
00854 overview_length -= g_bitmap_data.page_field_width << 1;
00855 }
00856 else
00857 {
00858 overview_length -= g_bitmap_data.page_field_width;
00859 }
00860
00861
00862 int cpi_shrink_x = x;
00863 if (pagebar->cpi_area.x > 0)
00864 {
00865 cpi_shrink_x -= g_bitmap_data.page_field_width;
00866 }
00867
00868 if (x > pagebar->cpi_area.x)
00869 {
00870 cpi_shrink_x -= pagebar->cpi_area.width;
00871 }
00872
00873 pagebar->current_page = cpi_shrink_x * pagebar->page_count / overview_length;
00874 if (pagebar->current_page < 1)
00875 {
00876
00877 pagebar->current_page = 1;
00878 }
00879 }
00880
00881 on_current_page_changed(pagebar);
00882 }
00883
00884
00885
00886
00887 gboolean on_pagebar_button_release_event(GtkWidget * widget,
00888 GdkEventButton * event,
00889 gpointer user_data)
00890 {
00891
00892 return TRUE;
00893 }
00894
00895 int on_current_page_changed(GtkPagebar * pagebar)
00896 {
00897 if (pagebar->last_selected_page == pagebar->current_page)
00898 {
00899 return 0;
00900 }
00901
00902 pagebar->last_selected_page = pagebar->current_page;
00903 gtk_pagebar_draw(pagebar);
00904
00905 g_signal_emit(pagebar,
00906 pagebar_signals[PAGE_SELECTED],
00907 0,
00908 pagebar->current_page);
00909 return 1;
00910 }
00911
00912 gboolean on_pagebar_button_press_event(GtkWidget * widget,
00913 GdkEventButton * event,
00914 gpointer user_data)
00915 {
00916 GtkPagebar *pagebar = GTK_PAGEBAR(user_data);
00917 int x = (int)(event->x);
00918 int y = (int)(event->y);
00919 pagebar_transfer_position(x, y, &x, &y, TRUE);
00920
00921 int pagebar_width = pagebar->pagebar_width;
00922 int pagebar_height = pagebar->pagebar_height;
00923
00924 if (pagebar->status == STATUS_NORMAL)
00925 {
00926 if (x >= pagebar->cpi_area.x &&
00927 x <= pagebar->cpi_area.x + pagebar->cpi_area.width)
00928 {
00929 pagebar_hit_test_on_cpi_overview(pagebar, x, y, pagebar_width, pagebar_height);
00930 }
00931 else if (x > g_bitmap_data.page_field_width && x < (pagebar_width - g_bitmap_data.page_field_width))
00932 {
00933 pagebar_hit_test_on_indicator_overview(pagebar, x, y, pagebar_width, pagebar_height);
00934 }
00935 else if (x <= g_bitmap_data.page_field_width)
00936 {
00937 pagebar->current_page = 1;
00938 on_current_page_changed(pagebar);
00939 }
00940 else if (x >= pagebar_width - g_bitmap_data.page_field_width)
00941 {
00942 pagebar->current_page = pagebar->page_count;
00943 on_current_page_changed(pagebar);
00944 }
00945 }
00946 else if (pagebar->status == STATUS_DETAILS)
00947 {
00948 pagebar_hit_test_details(pagebar, x, y);
00949 }
00950 else
00951 {
00952 pagebar_hit_test_shrink(pagebar, x, y, pagebar_width, pagebar_height);
00953 }
00954
00955 return TRUE;
00956 }
00957
00958 void gtk_pagebar_set_number_of_pages(GtkPagebar * pagebar,
00959 const unsigned int number)
00960 {
00961 g_return_if_fail(IS_GTK_PAGEBAR(pagebar));
00962 g_return_if_fail((number <= PAGEBAR_MAX_PAGES));
00963
00964 pagebar->page_count = number;
00965
00966 if (pagebar->page_count > pagebar->max_detailed_items)
00967 {
00968 pagebar->status = STATUS_NORMAL;
00969 }
00970 else
00971 {
00972 pagebar->status = STATUS_DETAILS;
00973 }
00974
00975 gtk_pagebar_draw(pagebar);
00976 }
00977
00978 unsigned int gtk_pagebar_get_number_of_pages(GtkPagebar * pagebar)
00979 {
00980 g_return_val_if_fail(IS_GTK_PAGEBAR(pagebar), -1);
00981
00982 return pagebar->page_count;
00983 }
00984
00985 gboolean gtk_pagebar_set_current_page(GtkPagebar * pagebar,
00986 const unsigned int current)
00987 {
00988 g_return_val_if_fail(IS_GTK_PAGEBAR(pagebar), FALSE);
00989
00990 if (pagebar->current_page != current)
00991 {
00992 pagebar->current_page = current;
00993 pagebar->last_selected_page = current;
00994 gtk_pagebar_draw(pagebar);
00995 }
00996 return TRUE;
00997 }
00998
00999 unsigned int gtk_pagebar_get_current_page(GtkPagebar * pagebar)
01000 {
01001 g_return_val_if_fail(IS_GTK_PAGEBAR(pagebar), -1);
01002
01003 return pagebar->current_page;
01004 }
01005
01006 gboolean gtk_pagebar_set_bookmark(GtkPagebar * pagebar,
01007 const unsigned int page)
01008 {
01009 g_return_val_if_fail(IS_GTK_PAGEBAR(pagebar), FALSE);
01010 g_return_val_if_fail((page > 0 && page <= pagebar->page_count), FALSE);
01011
01012 return add_bookmark(pagebar, page);
01013 }
01014
01015 gboolean gtk_pagebar_delete_bookmark(GtkPagebar * pagebar,
01016 const unsigned int page)
01017 {
01018 return remove_bookmark(pagebar, page);
01019 }
01020
01021 const GArray* gtk_pagebar_get_bookmarks(GtkPagebar * pagebar)
01022 {
01023 g_return_val_if_fail(IS_GTK_PAGEBAR(pagebar), NULL);
01024
01025 return pagebar->bookmarks;
01026 }
01027
01028 void gtk_pagebar_reset(GtkPagebar * pagebar)
01029 {
01030 g_return_if_fail(IS_GTK_PAGEBAR(pagebar));
01031
01032 pagebar->page_count = PAGEBAR_DEFAULT_PAGE_COUNT;
01033 pagebar->current_page = PAGEBAR_DEFAULT_CURRENT_PAGE;
01034 pagebar->status = STATUS_NORMAL;
01035
01036 if (pagebar->bookmarks)
01037 {
01038 g_array_free(pagebar->bookmarks, TRUE);
01039 pagebar->bookmarks = NULL;
01040 }
01041
01042
01043 }
01044
01045 unsigned int gtk_pagebar_get_minimal_height(GtkPagebar * pagebar)
01046 {
01047 g_return_val_if_fail(IS_GTK_PAGEBAR(pagebar), 0);
01048
01049 return MAX(g_bitmap_data.cpi_height, g_bitmap_data.page_field_height);
01050 }
01051
01052 gboolean is_page_marked(GArray * markers, int page_number)
01053 {
01054 if (markers == NULL)
01055 {
01056 return FALSE;
01057 }
01058
01059 unsigned int idx = 0;
01060 int mark_page = 0;
01061 for (; idx < markers->len; idx++)
01062 {
01063 mark_page = g_array_index(markers, guint, idx);
01064 if (mark_page == page_number)
01065 {
01066 return TRUE;
01067 }
01068 }
01069
01070 return FALSE;
01071 }
01072
01073 int pagebar_calibrate_x_of_marker(GtkPagebar * pagebar, const int origin_x,
01074 const int offset)
01075 {
01076 int x = origin_x;
01077 x -= offset;
01078
01079 int num_lines = x / (PAGEBAR_INDICATOR_SPACE + PAGEBAR_INDICATOR_LINE_WIDTH);
01080 if (num_lines > 0)
01081 {
01082 num_lines --;
01083 }
01084 x = offset + num_lines * (PAGEBAR_INDICATOR_SPACE + PAGEBAR_INDICATOR_LINE_WIDTH)
01085 - (g_bitmap_data.bookmark_icon_width >> 1);
01086
01087 return x;
01088 }
01089
01090 int pagebar_get_x_of_marker(GtkPagebar * pagebar, const int page_number,
01091 const int adjacent_pages)
01092 {
01093
01094
01095 int pagebar_width = pagebar->pagebar_width;
01096
01097
01098 int x = 0;
01099 int start_x = 0;
01100 int offset = 0;
01101
01102 if (page_number >= (int) (pagebar->current_page - adjacent_pages) &&
01103 page_number <= (int) (pagebar->current_page + adjacent_pages))
01104 {
01105 return -1;
01106 }
01107 else if (page_number == 1)
01108 {
01109 return -1;
01110 }
01111 else if (page_number == (int) pagebar->page_count)
01112 {
01113 return -1;
01114 }
01115
01116 if (page_number > (int) pagebar->current_page)
01117 {
01118
01119 start_x = pagebar->cpi_area.x + pagebar->cpi_area.width;
01120 int right_len = (pagebar_width - g_bitmap_data.page_field_width) - start_x;
01121
01122 x = (page_number - pagebar->current_page- adjacent_pages) * right_len /
01123 (pagebar->page_count - pagebar->current_page - adjacent_pages - 1);
01124
01125 offset = pagebar->right_indicator_offset;
01126 }
01127 else
01128 {
01129
01130 start_x = g_bitmap_data.page_field_width;
01131 int left_len = pagebar->cpi_area.x - start_x;
01132
01133 x = (page_number - 1) * left_len /
01134 (pagebar->current_page - 1 - adjacent_pages - 1);
01135
01136 offset = pagebar->left_indicator_offset;
01137 }
01138
01139
01140 return (pagebar_calibrate_x_of_marker(pagebar, x, offset) + start_x);
01141 }
01142
01143
01144
01145
01146 void pagebar_draw_markers(GtkPagebar * pagebar,
01147 const int bitmap,
01148 GArray * markers,
01149 const int adjacent_pages)
01150 {
01151 if (markers == NULL)
01152 {
01153 return;
01154 }
01155
01156 unsigned int idx = 0;
01157 guint mark_page = 0;
01158 int x = 0, y = 0;
01159 int display_x = 0, display_y = 0;
01160 int last_drawn_location = x;
01161
01162 for (; idx < markers->len; idx++)
01163 {
01164
01165 mark_page = g_array_index(markers, guint, idx);
01166
01167 x = pagebar_get_x_of_marker(pagebar, mark_page, adjacent_pages);
01168 if (x < 0)
01169 {
01170 continue;
01171 }
01172
01173
01174 if (x < last_drawn_location + g_bitmap_data.bookmark_icon_width)
01175 {
01176
01177 continue;
01178 }
01179
01180 y = pagebar->cpi_area.y + (g_bitmap_data.cpi_height - g_bitmap_data.page_field_height);
01181
01182
01183 pagebar_transfer_position(x, y, &display_x, &display_y, FALSE);
01184 gdk_draw_pixbuf(pagebar->pixmap, NULL,
01185 g_bitmap_data.bitmaps[bitmap], 0, 0, display_x, display_y, -1, -1,
01186 GDK_RGB_DITHER_NONE, 0, 0);
01187
01188 last_drawn_location = x;
01189 }
01190 }
01191
01192
01193
01194
01195
01196
01197
01198 void gtk_pagebar_draw(GtkPagebar * pagebar)
01199 {
01200 g_return_if_fail((IS_GTK_PAGEBAR(pagebar)));
01201
01202 if (!pagebar->pixmap)
01203 {
01204 return;
01205 }
01206
01207 if (pagebar->pagebar_width <= 1 || pagebar->pagebar_height <= 1)
01208 {
01209 return;
01210 }
01211
01212
01213 int width;
01214 int height;
01215 gdk_drawable_get_size(pagebar->pixmap, &width, &height);
01216 gdk_draw_rectangle(pagebar->pixmap,
01217 GTK_WIDGET(pagebar)->style->white_gc,
01218 TRUE,
01219 0,
01220 0,
01221 width,
01222 height);
01223
01224 pagebar_calculate_cpi(pagebar);
01225
01226 int line_x1 = 0;
01227 int line_x2 = 0;
01228 int line_y1 = pagebar->cpi_area.y + 1;
01229 int line_y2 = line_y1 + (g_bitmap_data.cpi_height - g_bitmap_data.page_field_height);
01230 int line_y_max = MAX(line_y1, line_y2);
01231 int line_y_min = MIN(line_y1, line_y2);
01232
01233 GdkColor color;
01234 color.pixel = 0;
01235 gdk_gc_set_foreground(pagebar->own_gc, &color);
01236 gdk_gc_set_line_attributes(pagebar->own_gc,
01237 PAGEBAR_HORIZONTAL_LINE_WIDTH,
01238 GDK_LINE_SOLID,
01239 GDK_CAP_PROJECTING,
01240 GDK_JOIN_MITER);
01241
01242
01243 gdk_draw_line(pagebar->pixmap,
01244 pagebar->own_gc,
01245 line_x1, line_y_min,
01246 (line_x1 + width), line_y_min);
01247
01248
01249 pagebar_transfer_position(line_x2, line_y_max, &line_x2, &line_y_max, FALSE);
01250 gdk_draw_line(pagebar->pixmap,
01251 pagebar->own_gc,
01252 line_x2 + 1, line_y_max,
01253 (line_x2 + pagebar->pagebar_width - 1), line_y_max);
01254
01255 if (pagebar->status == STATUS_DETAILS)
01256 {
01257
01258 pagebar_draw_details(pagebar);
01259 }
01260 else if (pagebar->status == STATUS_NORMAL)
01261 {
01262 pagebar_draw_overview(pagebar);
01263
01264 pagebar_draw_cpi_overview(pagebar);
01265
01266 pagebar_draw_markers(pagebar, BITMAP_BOOKMARK, pagebar->bookmarks,
01267 PAGEBAR_ADJACENT_PAGES_NUM);
01268 }
01269 else
01270 {
01271 pagebar_draw_overview(pagebar);
01272
01273 pagebar_draw_cpi_shrink(pagebar);
01274
01275 pagebar_draw_markers(pagebar, BITMAP_BOOKMARK, pagebar->bookmarks, 0);
01276 }
01277
01278
01279
01280
01281 gtk_widget_queue_draw(GTK_WIDGET(pagebar));
01282 }
01283
01284
01285
01286
01287 void pagebar_calculate_cpi(GtkPagebar * pagebar)
01288 {
01289 switch (pagebar->status)
01290 {
01291 case STATUS_NORMAL:
01292 pagebar_calculate_cpi_overview(pagebar);
01293 break;
01294 case STATUS_DETAILS:
01295 pagebar_calculate_cpi_details(pagebar);
01296 break;
01297 case STATUS_SHRINK:
01298 pagebar_calculate_cpi_shrink(pagebar);
01299 break;
01300 default:
01301 break;
01302 }
01303 }
01304
01305 void pagebar_calculate_cpi_details(GtkPagebar * pagebar)
01306 {
01307
01308
01309 pagebar->cpi_area.y = 0;
01310 }
01311
01312
01313
01314 void pagebar_calculate_cpi_overview(GtkPagebar * pagebar)
01315 {
01316
01317 int pagebar_width = pagebar->pagebar_width;
01318
01319
01320 int cpi_pages_num = 0;
01321 int cpi_width = 0;
01322 int cpi_height = MAX(g_bitmap_data.page_field_height, g_bitmap_data.cpi_height);
01323
01324 if (pagebar->current_page <= 1 + PAGEBAR_ADJACENT_PAGES_NUM)
01325 {
01326
01327 cpi_pages_num = pagebar->current_page + PAGEBAR_ADJACENT_PAGES_NUM;
01328
01329 cpi_width = (g_bitmap_data.page_field_width + PAGEBAR_CPI_ADJACENT_SPACE) * (cpi_pages_num - 1)+
01330 g_bitmap_data.cpi_width;
01331 if (pagebar->current_page == 1)
01332 {
01333 cpi_width -= (PAGEBAR_CPI_ADJACENT_SPACE - PAGEBAR_CPI_SPACE);
01334 }
01335 else
01336 {
01337 cpi_width -= ((PAGEBAR_CPI_ADJACENT_SPACE - PAGEBAR_CPI_SPACE) << 1);
01338 }
01339
01340 pagebar->cpi_area.x = 0;
01341 }
01342 else if (pagebar->current_page >= pagebar->page_count - PAGEBAR_ADJACENT_PAGES_NUM)
01343 {
01344
01345 cpi_pages_num = pagebar->page_count - pagebar->current_page +
01346 PAGEBAR_ADJACENT_PAGES_NUM + 1;
01347 cpi_width = (g_bitmap_data.page_field_width + PAGEBAR_CPI_ADJACENT_SPACE) * (cpi_pages_num - 1) +
01348 g_bitmap_data.cpi_width;
01349 if (pagebar->current_page == pagebar->page_count)
01350 {
01351 cpi_width -= (PAGEBAR_CPI_ADJACENT_SPACE - PAGEBAR_CPI_SPACE);
01352 }
01353 else
01354 {
01355 cpi_width -= ((PAGEBAR_CPI_ADJACENT_SPACE - PAGEBAR_CPI_SPACE) << 1);
01356 }
01357
01358 pagebar->cpi_area.x = pagebar_width - cpi_width;
01359 }
01360 else
01361 {
01362
01363 cpi_pages_num = (PAGEBAR_ADJACENT_PAGES_NUM << 1) + 1;
01364 cpi_width = (g_bitmap_data.page_field_width + PAGEBAR_CPI_ADJACENT_SPACE) * (cpi_pages_num - 1) +
01365 g_bitmap_data.cpi_width;
01366 cpi_width -= ((PAGEBAR_CPI_ADJACENT_SPACE - PAGEBAR_CPI_SPACE) << 1);
01367
01368
01369 int overview_length = pagebar_width - (g_bitmap_data.page_field_width << 1) - cpi_width;
01370
01371
01372 if (pagebar->current_page == (1 + PAGEBAR_ADJACENT_PAGES_NUM + 1))
01373 {
01374
01375
01376 pagebar->cpi_area.x = g_bitmap_data.page_field_width + PAGEBAR_CPI_ADJACENT_SPACE;
01377 }
01378 else if (pagebar->current_page == (pagebar->page_count - PAGEBAR_ADJACENT_PAGES_NUM - 1))
01379 {
01380
01381 pagebar->cpi_area.x = pagebar_width - g_bitmap_data.page_field_width -
01382 PAGEBAR_CPI_ADJACENT_SPACE - cpi_width;
01383 }
01384 else
01385 {
01386 pagebar->cpi_area.x = g_bitmap_data.page_field_width +
01387 (pagebar->current_page - PAGEBAR_ADJACENT_PAGES_NUM - 2) *
01388 overview_length / (pagebar->page_count - cpi_pages_num - 2);
01389 }
01390
01391 }
01392
01393 pagebar->cpi_area.width = cpi_width;
01394 pagebar->cpi_area.height = cpi_height;
01395
01396
01397 pagebar->cpi_area.y = 0;
01398 }
01399
01400 void pagebar_calculate_cpi_shrink(GtkPagebar * pagebar)
01401 {
01402 int pagebar_width = pagebar->pagebar_width;
01403
01404
01405 pagebar->cpi_area.width = g_bitmap_data.cpi_width;
01406 pagebar->cpi_area.height = g_bitmap_data.cpi_height;
01407
01408 pagebar->cpi_area.y = 0;
01409 if (pagebar->current_page == 1)
01410 {
01411 pagebar->cpi_area.x = 0;
01412 return;
01413 }
01414
01415 if (pagebar->current_page == pagebar->page_count)
01416 {
01417 pagebar->cpi_area.x = pagebar_width - g_bitmap_data.cpi_width;
01418 return;
01419 }
01420
01421
01422 int overview_length = pagebar_width - (g_bitmap_data.page_field_width << 1) - g_bitmap_data.cpi_width;
01423 int cpi_overview_x = pagebar->current_page * overview_length / (pagebar->page_count - 2);
01424 pagebar->cpi_area.x = g_bitmap_data.page_field_width + cpi_overview_x;
01425
01426 }
01427
01428 void pagebar_draw_details(GtkPagebar * pagebar)
01429 {
01430
01431
01432
01433
01434 int x = 0;
01435 int y = 0;
01436 int inc_length = 0;
01437 int w = 0, h = 0;
01438 char text[16] = { 0 };
01439
01440
01441 pagebar->cpi_area.x = x;
01442
01443
01444 GdkColor color;
01445 color.pixel = PAGEBAR_NEXT_PAGE_TEXT_COLOR;
01446 gdk_gc_set_foreground(pagebar->own_gc, &color);
01447
01448
01449 int display_x = 0, display_y = 0;
01450
01451 unsigned int idx = 1;
01452 for (; idx <= pagebar->page_count; ++idx)
01453 {
01454 int bitmap_kind = BITMAP_SUCC_CPI;
01455 GdkGC *gc = GTK_WIDGET(pagebar)->style->black_gc;
01456 int size_x = 0;
01457 int size_y = 0;
01458 if (idx == pagebar->current_page)
01459 {
01460
01461 y = pagebar->cpi_area.y;
01462
01463 if (is_page_marked(pagebar->bookmarks, idx))
01464 {
01465 bitmap_kind = BITMAP_CPI_BOOKMARK;
01466 }
01467 else
01468 {
01469 bitmap_kind = BITMAP_CPI;
01470 }
01471
01472 pagebar_transfer_position(x, y, &display_x, &display_y, FALSE);
01473 gdk_draw_pixbuf(pagebar->pixmap,
01474 NULL, g_bitmap_data.bitmaps[bitmap_kind],
01475 0, 0, display_x, display_y,
01476 g_bitmap_data.cpi_width,
01477 g_bitmap_data.cpi_height,
01478 GDK_RGB_DITHER_NONE, 0, 0);
01479
01480 inc_length = g_bitmap_data.cpi_width;
01481 gc = GTK_WIDGET(pagebar)->style->white_gc;
01482
01483 size_x = g_bitmap_data.cpi_width;
01484 size_y = g_bitmap_data.cpi_height;
01485 }
01486 else
01487 {
01488 if (idx < pagebar->current_page)
01489 {
01490 if (is_page_marked(pagebar->bookmarks, idx))
01491 {
01492 bitmap_kind = BITMAP_PREV_CPI_BOOKMARK;
01493 }
01494 else
01495 {
01496 bitmap_kind = BITMAP_PREV_CPI;
01497 }
01498
01499 gc = GTK_WIDGET(pagebar)->style->white_gc;
01500 }
01501 else
01502 {
01503 if (is_page_marked(pagebar->bookmarks, idx))
01504 {
01505 bitmap_kind = BITMAP_SUCC_CPI_BOOKMARK;
01506 }
01507 else
01508 {
01509 bitmap_kind = BITMAP_SUCC_CPI;
01510 }
01511
01512 gc = pagebar->own_gc;
01513 }
01514
01515
01516 y = pagebar->cpi_area.y + (g_bitmap_data.cpi_height - g_bitmap_data.page_field_height);
01517
01518 pagebar_transfer_position(x, y, &display_x, &display_y, FALSE);
01519 gdk_draw_pixbuf(pagebar->pixmap,
01520 NULL, g_bitmap_data.bitmaps[bitmap_kind],
01521 0, 0, display_x, display_y,
01522 -1, -1,
01523 GDK_RGB_DITHER_NONE, 0, 0);
01524
01525 inc_length = g_bitmap_data.page_field_width;
01526 size_x = g_bitmap_data.page_field_width;
01527 size_y = g_bitmap_data.page_field_height;
01528 }
01529
01530 sprintf(text, "%d", idx);
01531 pango_layout_set_text(pagebar->pango_layout, text, -1);
01532 pango_layout_get_pixel_size(pagebar->pango_layout, (int *)&w, (int *)&h);
01533
01534 gdk_draw_layout(pagebar->pixmap,
01535 gc,
01536 display_x + (size_x - w) / 2,
01537 display_y + (size_y - h) / 2,
01538 pagebar->pango_layout);
01539
01540 if (idx == pagebar->current_page || idx == (pagebar->current_page - 1))
01541 {
01542 x += (inc_length + PAGEBAR_CPI_SPACE);
01543 }
01544 else
01545 {
01546 x += (inc_length + PAGEBAR_CPI_ADJACENT_SPACE);
01547 }
01548 }
01549 }
01550
01551 void pagebar_draw_overview(GtkPagebar * pagebar)
01552 {
01553 int pagebar_width = pagebar->pagebar_width;
01554
01555
01556
01557 int left_length = 0, right_length = 0;
01558 int cpi_right = pagebar->cpi_area.x + pagebar->cpi_area.width;
01559
01560 int x = 0;
01561 int y = pagebar->cpi_area.y + (g_bitmap_data.cpi_height - g_bitmap_data.page_field_height) +
01562 ((g_bitmap_data.page_field_height - PAGEBAR_INDICATOR_LINE_HEIGHT) >> 1) + 2;
01563 int display_x = 0, display_y = 0;
01564
01565
01566 pagebar->left_indicator_offset = 0;
01567 pagebar->right_indicator_offset = 0;
01568
01569 char text[16] = { 0 };
01570 unsigned int w = 0, h = 0;
01571
01572
01573 gboolean draw_first = TRUE;
01574 gboolean draw_last = TRUE;
01575 if (pagebar->cpi_area.x == 0)
01576 {
01577 draw_first = FALSE;
01578 right_length = pagebar_width - g_bitmap_data.page_field_width - cpi_right;
01579 x = cpi_right;
01580 }
01581 if (pagebar->cpi_area.x == (pagebar_width - pagebar->cpi_area.width))
01582 {
01583 draw_last = FALSE;
01584 left_length = pagebar->cpi_area.x - g_bitmap_data.page_field_width;
01585 x = g_bitmap_data.page_field_width;
01586 }
01587 else
01588 {
01589 left_length = pagebar->cpi_area.x - g_bitmap_data.page_field_width;
01590 right_length = pagebar_width - cpi_right - g_bitmap_data.page_field_width;
01591 x = g_bitmap_data.page_field_width;
01592 }
01593
01594 int left_indicators_num = left_length / (PAGEBAR_INDICATOR_LINE_WIDTH +
01595 PAGEBAR_INDICATOR_SPACE);
01596 if (left_indicators_num > 0)
01597 {
01598 int left_indicators_len = left_indicators_num * (PAGEBAR_INDICATOR_LINE_WIDTH +
01599 PAGEBAR_INDICATOR_SPACE);
01600 pagebar->left_indicator_offset = (((PAGEBAR_INDICATOR_SPACE << 1) +
01601 PAGEBAR_INDICATOR_LINE_WIDTH) >> 1);
01602 if (left_indicators_len != left_length)
01603 {
01604 pagebar->left_indicator_offset += ((left_length - left_indicators_len) >> 1);
01605 }
01606 left_indicators_num--;
01607 }
01608
01609 int right_indicators_num = right_length / (PAGEBAR_INDICATOR_LINE_WIDTH +
01610 PAGEBAR_INDICATOR_SPACE);
01611 if (right_indicators_num > 0)
01612 {
01613 int right_indicators_len = right_indicators_num * (PAGEBAR_INDICATOR_LINE_WIDTH +
01614 PAGEBAR_INDICATOR_SPACE);
01615 pagebar->right_indicator_offset = (((PAGEBAR_INDICATOR_SPACE << 1) +
01616 PAGEBAR_INDICATOR_LINE_WIDTH) >> 1);
01617 if (right_indicators_len != right_length)
01618 {
01619 pagebar->right_indicator_offset += ((right_length - right_indicators_len) >> 1);
01620 }
01621 right_indicators_num--;
01622 }
01623
01624
01625 GdkColor color;
01626 color.pixel = PAGEBAR_INDICATOR_COLOR;
01627 gdk_gc_set_foreground(pagebar->own_gc, &color);
01628 gdk_gc_set_line_attributes(pagebar->own_gc,
01629 PAGEBAR_INDICATOR_LINE_WIDTH,
01630 GDK_LINE_SOLID,
01631 GDK_CAP_PROJECTING,
01632 GDK_JOIN_MITER);
01633
01634 x += pagebar->left_indicator_offset;
01635 int idx = 0;
01636 while (idx < left_indicators_num)
01637 {
01638 pagebar_transfer_position(x, y, &display_x, &display_y, FALSE);
01639 gdk_draw_line(pagebar->pixmap,
01640 pagebar->own_gc,
01641 display_x, display_y,
01642 display_x, display_y + PAGEBAR_INDICATOR_LINE_HEIGHT);
01643
01644 idx++;
01645 x += (PAGEBAR_INDICATOR_SPACE + PAGEBAR_INDICATOR_LINE_WIDTH);
01646 }
01647
01648 color.pixel = 0;
01649 gdk_gc_set_foreground(pagebar->own_gc, &color);
01650 x = cpi_right + pagebar->right_indicator_offset;
01651 idx = 0;
01652 while (idx < right_indicators_num)
01653 {
01654 pagebar_transfer_position(x, y, &display_x, &display_y, FALSE);
01655 gdk_draw_line(pagebar->pixmap,
01656 pagebar->own_gc,
01657 display_x, display_y,
01658 display_x, display_y + PAGEBAR_INDICATOR_LINE_HEIGHT);
01659
01660 idx++;
01661 x += (PAGEBAR_INDICATOR_SPACE + PAGEBAR_INDICATOR_LINE_WIDTH);
01662 }
01663
01664
01665 int bitmap_kind = BITMAP_SUCC_CPI;
01666
01667 y = pagebar->cpi_area.y + (g_bitmap_data.cpi_height - g_bitmap_data.page_field_height);
01668 if (draw_first)
01669 {
01670
01671 x = 0;
01672
01673 if (is_page_marked(pagebar->bookmarks, 1))
01674 {
01675 bitmap_kind = BITMAP_PREV_CPI_BOOKMARK;
01676 }
01677 else
01678 {
01679 bitmap_kind = BITMAP_PREV_CPI;
01680 }
01681
01682 pagebar_transfer_position(x, y, &display_x, &display_y, FALSE);
01683 gdk_draw_pixbuf(pagebar->pixmap, NULL,
01684 g_bitmap_data.bitmaps[bitmap_kind],
01685 0, 0, display_x, display_y, -1, -1,
01686 GDK_RGB_DITHER_NONE, 0, 0);
01687
01688 sprintf(text, "1");
01689 pango_layout_set_text(pagebar->pango_layout, text, -1);
01690 pango_layout_get_pixel_size(pagebar->pango_layout, (int *)&w,(int*)&h);
01691
01692 gdk_draw_layout(pagebar->pixmap,
01693 GTK_WIDGET(pagebar)->style->white_gc,
01694 display_x + ((g_bitmap_data.page_field_width - w) >> 1),
01695 display_y + ((g_bitmap_data.page_field_height - h) >> 1),
01696 pagebar->pango_layout);
01697 }
01698
01699 if (draw_last)
01700 {
01701
01702 x = pagebar_width - g_bitmap_data.page_field_width;
01703
01704 if (is_page_marked(pagebar->bookmarks, pagebar->page_count))
01705 {
01706 bitmap_kind = BITMAP_SUCC_CPI_BOOKMARK;
01707 }
01708 else
01709 {
01710 bitmap_kind = BITMAP_SUCC_CPI;
01711 }
01712
01713 pagebar_transfer_position(x, y, &display_x, &display_y, FALSE);
01714 gdk_draw_pixbuf(pagebar->pixmap,
01715 NULL,
01716 g_bitmap_data.bitmaps[bitmap_kind],
01717 0, 0, display_x, display_y, -1, -1,
01718 GDK_RGB_DITHER_NONE, 0, 0);
01719
01720
01721 GdkColor color;
01722 color.pixel = PAGEBAR_LAST_PAGE_TEXT_COLOR;
01723 gdk_gc_set_foreground(pagebar->own_gc, &color);
01724
01725 sprintf(text, "%d", pagebar->page_count);
01726 pango_layout_set_text(pagebar->pango_layout, text, -1);
01727 pango_layout_get_pixel_size(pagebar->pango_layout, (int *)&w, (int *)&h);
01728
01729 gdk_draw_layout(pagebar->pixmap,
01730 pagebar->own_gc,
01731 display_x + ((g_bitmap_data.page_field_width - w) >> 1),
01732 display_y + ((g_bitmap_data.page_field_height - h) >> 1),
01733 pagebar->pango_layout);
01734 }
01735 }
01736
01737 void pagebar_draw_cpi_overview(GtkPagebar * pagebar)
01738 {
01739 unsigned int cpi_pages_count = 0;
01740 unsigned int idx = 0;
01741 int x = pagebar->cpi_area.x;
01742 int y = 0;
01743 char text[16] = { 0 };
01744 int w = 0, h = 0;
01745 int inc_length = 0;
01746 int display_x = 0, display_y = 0;
01747
01748
01749
01750
01751 if (pagebar->current_page <= 1 + PAGEBAR_ADJACENT_PAGES_NUM)
01752 {
01753
01754 idx = 1;
01755 cpi_pages_count = pagebar->current_page + PAGEBAR_ADJACENT_PAGES_NUM;
01756 }
01757 else if (pagebar->current_page >= pagebar->page_count - PAGEBAR_ADJACENT_PAGES_NUM)
01758 {
01759
01760 idx = pagebar->current_page - PAGEBAR_ADJACENT_PAGES_NUM;
01761 cpi_pages_count = pagebar->page_count;
01762 }
01763 else
01764 {
01765 idx = pagebar->current_page - PAGEBAR_ADJACENT_PAGES_NUM;
01766 cpi_pages_count = pagebar->current_page + PAGEBAR_ADJACENT_PAGES_NUM;
01767 }
01768
01769 int bitmap_kind = BITMAP_SUCC_CPI;
01770
01771
01772 GdkColor color;
01773 color.pixel = PAGEBAR_NEXT_PAGE_TEXT_COLOR;
01774 gdk_gc_set_foreground(pagebar->own_gc, &color);
01775
01776 for (; idx <= cpi_pages_count; ++idx)
01777 {
01778 GdkGC *gc = GTK_WIDGET(pagebar)->style->black_gc;
01779 int size_x = 0;
01780 int size_y = 0;
01781 if (idx == pagebar->current_page)
01782 {
01783
01784 y = pagebar->cpi_area.y;
01785
01786 if (is_page_marked(pagebar->bookmarks, idx))
01787 {
01788 bitmap_kind = BITMAP_CPI_BOOKMARK;
01789 }
01790 else
01791 {
01792 bitmap_kind = BITMAP_CPI;
01793 }
01794
01795 pagebar_transfer_position(x, y, &display_x, &display_y, FALSE);
01796 gdk_draw_pixbuf(pagebar->pixmap,
01797 NULL, g_bitmap_data.bitmaps[bitmap_kind],
01798 0, 0, display_x, display_y,
01799 g_bitmap_data.cpi_width,
01800 g_bitmap_data.cpi_height,
01801 GDK_RGB_DITHER_NONE, 0, 0);
01802
01803 inc_length = g_bitmap_data.cpi_width;
01804 gc = GTK_WIDGET(pagebar)->style->white_gc;
01805
01806 size_x = g_bitmap_data.cpi_width;
01807 size_y = g_bitmap_data.cpi_height;
01808 }
01809 else
01810 {
01811
01812 y = pagebar->cpi_area.y + (g_bitmap_data.cpi_height - g_bitmap_data.page_field_height);
01813
01814 if (idx < pagebar->current_page)
01815 {
01816 if (is_page_marked(pagebar->bookmarks, idx))
01817 {
01818 bitmap_kind = BITMAP_PREV_CPI_BOOKMARK;
01819 }
01820 else
01821 {
01822 bitmap_kind = BITMAP_PREV_CPI;
01823 }
01824
01825 gc = GTK_WIDGET(pagebar)->style->white_gc;
01826 }
01827 else
01828 {
01829 if (is_page_marked(pagebar->bookmarks, idx))
01830 {
01831 bitmap_kind = BITMAP_SUCC_CPI_BOOKMARK;
01832 }
01833 else
01834 {
01835 bitmap_kind = BITMAP_SUCC_CPI;
01836 }
01837
01838 gc = pagebar->own_gc;
01839 }
01840
01841 pagebar_transfer_position(x, y, &display_x, &display_y, FALSE);
01842 gdk_draw_pixbuf(pagebar->pixmap,
01843 NULL, g_bitmap_data.bitmaps[bitmap_kind],
01844 0, 0, display_x, display_y,
01845 -1, -1,
01846 GDK_RGB_DITHER_NONE, 0, 0);
01847
01848 inc_length = g_bitmap_data.page_field_width;
01849
01850 size_x = g_bitmap_data.page_field_width;
01851 size_y = g_bitmap_data.page_field_height;
01852 }
01853
01854 sprintf(text, "%d", idx);
01855 pango_layout_set_text(pagebar->pango_layout, text, -1);
01856 pango_layout_get_pixel_size(pagebar->pango_layout, (int *)&w, (int *)&h);
01857
01858 pagebar_transfer_position(x, y, &display_x, &display_y, FALSE);
01859 gdk_draw_layout(pagebar->pixmap,
01860 gc,
01861 display_x + (size_x - w) / 2,
01862 display_y + (size_y - h) / 2,
01863 pagebar->pango_layout);
01864
01865 if (idx == pagebar->current_page || idx == pagebar->current_page - 1)
01866 {
01867 x += (inc_length + PAGEBAR_CPI_SPACE);
01868 }
01869 else
01870 {
01871 x += (inc_length + PAGEBAR_CPI_ADJACENT_SPACE);
01872 }
01873 }
01874 }
01875
01876 void pagebar_draw_cpi_shrink(GtkPagebar * pagebar)
01877 {
01878 int x = pagebar->cpi_area.x;
01879 int y = pagebar->cpi_area.y;
01880 char text[16] = { 0 };
01881 int w = 0, h = 0;
01882
01883 int bitmap_kind = BITMAP_CPI;
01884
01885 if (is_page_marked(pagebar->bookmarks, pagebar->current_page))
01886 {
01887 bitmap_kind = BITMAP_CPI_BOOKMARK;
01888 }
01889
01890 pagebar_transfer_position(x, y, &x, &y, FALSE);
01891 gdk_draw_pixbuf(pagebar->pixmap,
01892 NULL, g_bitmap_data.bitmaps[bitmap_kind],
01893 0, 0, x, y,
01894 g_bitmap_data.cpi_width,
01895 g_bitmap_data.cpi_height,
01896 GDK_RGB_DITHER_NONE, 0, 0);
01897
01898 sprintf(text, "%d", pagebar->current_page);
01899 pango_layout_set_text(pagebar->pango_layout, text, -1);
01900 pango_layout_get_pixel_size(pagebar->pango_layout, (int *)&w, (int *)&h);
01901 gdk_draw_layout(pagebar->pixmap,
01902 GTK_WIDGET(pagebar)->style->white_gc,
01903 x + (g_bitmap_data.cpi_width - w) / 2,
01904 y + (g_bitmap_data.cpi_height - h) / 2,
01905 pagebar->pango_layout);
01906
01907 }
01908
01909 void gtk_pagebar_update(GtkPagebar * pagebar)
01910 {
01911 gtk_pagebar_draw(pagebar);
01912 }