mirror of
https://git.pwmt.org/pwmt/zathura.git
synced 2025-01-30 02:34:56 +01:00
draw highlights in the page view widget
This commit is contained in:
parent
62708d3d44
commit
81bec2e528
3 changed files with 107 additions and 36 deletions
|
@ -4,14 +4,22 @@
|
|||
#include "render.h"
|
||||
#include <girara/utils.h>
|
||||
#include <girara/settings.h>
|
||||
#include <girara/datastructures.h>
|
||||
|
||||
G_DEFINE_TYPE(ZathuraPageView, zathura_page_view, GTK_TYPE_DRAWING_AREA)
|
||||
|
||||
typedef struct pv_rect_s
|
||||
{
|
||||
zathura_rectangle_t rect;
|
||||
int linkid;
|
||||
} pv_rect_t;
|
||||
|
||||
typedef struct zathura_page_view_private_s {
|
||||
zathura_page_t* page;
|
||||
zathura_t* zathura;
|
||||
cairo_surface_t* surface; /** Cairo surface */
|
||||
GStaticMutex lock; /**< Lock */
|
||||
girara_list_t* rectangles;
|
||||
} zathura_page_view_private_t;
|
||||
|
||||
#define ZATHURA_PAGE_VIEW_GET_PRIVATE(obj) \
|
||||
|
@ -54,6 +62,7 @@ zathura_page_view_init(ZathuraPageView* widget)
|
|||
zathura_page_view_private_t* priv = ZATHURA_PAGE_VIEW_GET_PRIVATE(widget);
|
||||
priv->page = NULL;
|
||||
priv->surface = NULL;
|
||||
priv->rectangles = girara_list_new2(g_free);
|
||||
g_static_mutex_init(&(priv->lock));
|
||||
|
||||
/* we want mouse events */
|
||||
|
@ -141,8 +150,35 @@ zathura_page_view_expose(GtkWidget* widget, GdkEventExpose* event)
|
|||
|
||||
cairo_set_source_surface(cairo, priv->surface, 0, 0);
|
||||
cairo_paint(cairo);
|
||||
|
||||
cairo_restore(cairo);
|
||||
|
||||
/* draw rectangles */
|
||||
char* font = NULL;
|
||||
girara_setting_get(priv->zathura->ui.session, "font", &font);
|
||||
|
||||
float transparency = 0.5;
|
||||
girara_setting_get(priv->zathura->ui.session, "highlight-transparency", &transparency);
|
||||
|
||||
if (font != NULL) {
|
||||
cairo_select_font_face(cairo, font, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
|
||||
}
|
||||
|
||||
GIRARA_LIST_FOREACH(priv->rectangles, pv_rect_t*, iter, rect)
|
||||
if (rect->linkid >= 0) {
|
||||
/* draw text */
|
||||
cairo_set_font_size(cairo, 10);
|
||||
cairo_move_to(cairo, rect->rect.x1 + 1, rect->rect.y1 - 1);
|
||||
char* link_number = g_strdup_printf("%i", rect->linkid);
|
||||
cairo_show_text(cairo, link_number);
|
||||
g_free(link_number);
|
||||
}
|
||||
|
||||
/* draw rectangle */
|
||||
GdkColor color = priv->zathura->ui.colors.highlight_color;
|
||||
cairo_set_source_rgba(cairo, color.red, color.green, color.blue, transparency);
|
||||
cairo_rectangle(cairo, rect->rect.x1, rect->rect.y1, (rect->rect.x2 - rect->rect.x1), (rect->rect.y2 - rect->rect.y1));
|
||||
cairo_fill(cairo);
|
||||
GIRARA_LIST_FOREACH_END(priv->rectangles, pv_rect_t*, iter, rect);
|
||||
} else {
|
||||
/* set background color */
|
||||
cairo_set_source_rgb(cairo, 255, 255, 255);
|
||||
|
@ -205,5 +241,48 @@ static void
|
|||
zathura_page_view_size_allocate(GtkWidget* widget, GdkRectangle* allocation)
|
||||
{
|
||||
GTK_WIDGET_CLASS(zathura_page_view_parent_class)->size_allocate(widget, allocation);
|
||||
zathura_page_view_clear_rectangles(ZATHURA_PAGE_VIEW(widget));
|
||||
zathura_page_view_update_surface(ZATHURA_PAGE_VIEW(widget), NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
redraw_rect(ZathuraPageView* widget, pv_rect_t* rectangle)
|
||||
{
|
||||
/* cause the rect to be drawn */
|
||||
GdkRectangle grect;
|
||||
grect.x = rectangle->rect.x1;
|
||||
grect.y = rectangle->rect.y2;
|
||||
grect.width = rectangle->rect.x2 - rectangle->rect.x1;
|
||||
grect.height = rectangle->rect.y1 - rectangle->rect.y2;
|
||||
gdk_window_invalidate_rect(GTK_WIDGET(widget)->window, &grect, TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
zathura_page_view_draw_rectangle(ZathuraPageView* widget, zathura_rectangle_t* rectangle, int linkid)
|
||||
{
|
||||
g_return_if_fail(widget != NULL);
|
||||
if (rectangle == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
zathura_page_view_private_t* priv = ZATHURA_PAGE_VIEW_GET_PRIVATE(widget);
|
||||
|
||||
pv_rect_t* rect = g_malloc0(sizeof(pv_rect_t));
|
||||
rect->rect = *rectangle;
|
||||
rect->linkid = linkid;
|
||||
|
||||
girara_list_append(priv->rectangles, rect);
|
||||
redraw_rect(widget, rect);
|
||||
}
|
||||
|
||||
void
|
||||
zathura_page_view_clear_rectangles(ZathuraPageView* widget)
|
||||
{
|
||||
g_return_if_fail(widget != NULL);
|
||||
|
||||
zathura_page_view_private_t* priv = ZATHURA_PAGE_VIEW_GET_PRIVATE(widget);
|
||||
GIRARA_LIST_FOREACH(priv->rectangles, pv_rect_t*, iter, rect)
|
||||
redraw_rect(widget, rect);
|
||||
GIRARA_LIST_FOREACH_END(priv->rectangles, pv_rect_t*, iter, rect);
|
||||
girara_list_clear(priv->rectangles);
|
||||
}
|
||||
|
|
|
@ -6,8 +6,11 @@
|
|||
#include <gtk/gtk.h>
|
||||
#include "document.h"
|
||||
|
||||
/** The page view widget. The widget handles all the rendering on its own. It
|
||||
* only has to be resized. */
|
||||
/**
|
||||
* The page view widget. The widget handles all the rendering on its own. It
|
||||
* only has to be resized. The widget also manages and handles all the
|
||||
* rectangles for highlighting.
|
||||
* */
|
||||
typedef struct zathura_page_view_s ZathuraPageView;
|
||||
typedef struct zathura_page_view_class_s ZathuraPageViewClass;
|
||||
|
||||
|
@ -32,20 +35,35 @@ struct zathura_page_view_class_s {
|
|||
#define ZATHURA_PAGE_VIEW_GET_CLASS \
|
||||
(G_TYPE_INSTANCE_GET_CLASS ((obj), ZATHURA_TYPE_PAGE_VIEW, ZathuraPageViewclass))
|
||||
|
||||
/** Returns the type of the page view widget.
|
||||
/**
|
||||
* Returns the type of the page view widget.
|
||||
* @return the type
|
||||
*/
|
||||
GType zathura_page_view_get_type(void);
|
||||
/** Create a page view widget.
|
||||
/**
|
||||
* Create a page view widget.
|
||||
* @param page the page to be displayed
|
||||
* @return a page view widget
|
||||
*/
|
||||
GtkWidget* zathura_page_view_new(zathura_page_t* page);
|
||||
/** Update the widget's surface. This should only be called from the render
|
||||
/**
|
||||
* Update the widget's surface. This should only be called from the render
|
||||
* thread.
|
||||
* @param widget the widget
|
||||
* @param surface the new surface
|
||||
*/
|
||||
void zathura_page_view_update_surface(ZathuraPageView* widget, cairo_surface_t* surface);
|
||||
/**
|
||||
* Draw a rectangle to mark links or search results
|
||||
* @param widget the widget
|
||||
* @param rectangle the rectangle
|
||||
* @param linkid the link id if it's a link, -1 otherwise
|
||||
*/
|
||||
void zathura_page_view_draw_rectangle(ZathuraPageView* widget, zathura_rectangle_t* rectangle, int linkid);
|
||||
/**
|
||||
* Clear all rectangles.
|
||||
* @param widget the widget
|
||||
*/
|
||||
void zathura_page_view_clear_rectangles(ZathuraPageView* widget);
|
||||
|
||||
#endif
|
||||
|
|
34
shortcuts.c
34
shortcuts.c
|
@ -12,6 +12,7 @@
|
|||
#include "zathura.h"
|
||||
#include "render.h"
|
||||
#include "utils.h"
|
||||
#include "page_view_widget.h"
|
||||
|
||||
bool
|
||||
sc_abort(girara_session_t* session, girara_argument_t* UNUSED(argument),
|
||||
|
@ -106,12 +107,6 @@ sc_follow(girara_session_t* session, girara_argument_t* UNUSED(argument),
|
|||
return false;
|
||||
}
|
||||
|
||||
char* font = NULL;
|
||||
girara_setting_get(session, "font", &font);
|
||||
|
||||
float transparency = 0.5;
|
||||
girara_setting_get(session, "highlight-transparency", &transparency);
|
||||
|
||||
unsigned int link_id = 0;
|
||||
for (unsigned int page_id = 0; page_id < zathura->document->number_of_pages; page_id++) {
|
||||
zathura_page_t* page = zathura->document->pages[page_id];
|
||||
|
@ -119,6 +114,8 @@ sc_follow(girara_session_t* session, girara_argument_t* UNUSED(argument),
|
|||
continue;
|
||||
}
|
||||
|
||||
zathura_page_view_clear_rectangles(ZATHURA_PAGE_VIEW(page->drawing_area));
|
||||
|
||||
// TODO: is page visible?
|
||||
girara_list_t* links = zathura_page_links_get(page);
|
||||
if (links == NULL || girara_list_size(links) == 0) {
|
||||
|
@ -127,35 +124,12 @@ sc_follow(girara_session_t* session, girara_argument_t* UNUSED(argument),
|
|||
}
|
||||
|
||||
GIRARA_LIST_FOREACH(links, zathura_link_t*, iter, link)
|
||||
cairo_t* cairo = gdk_cairo_create(page->drawing_area->window);
|
||||
if (font != NULL) {
|
||||
cairo_select_font_face(cairo, font, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
|
||||
}
|
||||
|
||||
zathura_rectangle_t position = recalc_rectangle(page, link->position);
|
||||
|
||||
/* draw text */
|
||||
cairo_set_font_size(cairo, 10);
|
||||
cairo_move_to(cairo, position.x1 + 1, position.y1 - 1);
|
||||
char* link_number = g_strdup_printf("%i", ++link_id);
|
||||
cairo_show_text(cairo, link_number);
|
||||
g_free(link_number);
|
||||
|
||||
/* draw rectangle */
|
||||
GdkColor color = zathura->ui.colors.highlight_color;
|
||||
cairo_set_source_rgba(cairo, color.red, color.green, color.blue, transparency);
|
||||
cairo_rectangle(cairo, position.x1, position.y1, (position.x2 - position.x1), (position.y2 - position.y1));
|
||||
cairo_fill(cairo);
|
||||
|
||||
cairo_destroy(cairo);
|
||||
zathura_page_view_draw_rectangle(ZATHURA_PAGE_VIEW(page->drawing_area), &position, ++link_id);
|
||||
GIRARA_LIST_FOREACH_END(links, zathura_link_t*, iter, link);
|
||||
girara_list_free(links);
|
||||
}
|
||||
|
||||
if (font != NULL) {
|
||||
g_free(font);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue