/* Copyright (C) 2001-2002 Kenichi Suto
*
* 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 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <gdk/gdkx.h>
#include "defs.h"
#include "global.h"
#include "canvas.h"
#include "contentarea.h"
#include "link.h"
#include "select.h"
#include "eb.h"
#include "popup.h"
GtkWidget *popup=NULL;
static GtkWidget *popup_scroll=NULL;
static GtkWidget *popup_viewport=NULL;
static const title_height = 22;
static gint align_x = 10;
static gint align_y = 10;
GList *current_result=NULL;
static CONTENT_AREA *popup_area=NULL;
static gint close_popup(GtkWidget *widget, gpointer data){
gtk_widget_destroy(popup);
gtk_widget_grab_focus(popup);
gtk_grab_add(popup);
popup = NULL;
destroy_canvas(popup_area->canvas);
destroy_content_area(popup_area);
}
static gint popup_click_event (GtkWidget *widget, GdkEventButton *event)
{
gchar *text = NULL;
SEARCH_RESULT *rp;
if(event->type == GDK_BUTTON_PRESS){
if (event->button == 1){
gtk_widget_destroy(popup);
popup = NULL;
destroy_canvas(popup_area->canvas);
destroy_content_area(popup_area);
} else if ((event->button == 2) || (event->button == 3)){
if(!current_result)
return(FALSE);
if (event->button == 2) {
if(g_list_previous(current_result) == NULL){
return(FALSE);
}
current_result = g_list_previous(current_result);
} else {
if(g_list_next(current_result) == NULL){
return(FALSE);
}
current_result = g_list_next(current_result);
}
if(current_result == NULL)
return(0);
rp = (SEARCH_RESULT *)(current_result->data);
current_book_info = rp->book_info;
if(current_result){
text = ebook_get_text(rp->book_info,
rp->pos_text.page,
rp->pos_text.offset);
show_popup(rp->book_info, text);
free(text);
}
}
}
return(FALSE);
}
static void show_in_popup(BOOK_INFO *binfo, gchar *text){
show_popup(binfo, text);
}
static gint title_click_event (GtkWidget *widget, GdkEventButton *event, gpointer data)
{
gchar *text = NULL;
SEARCH_RESULT *rp;
if(event->type == GDK_BUTTON_PRESS){
if ((event->button == 2) || (event->button == 3)){
return(FALSE);
}
if((strcmp(data, "<") == 0) ||
(strcmp(data, ">") == 0)){
if(strcmp(data, "<") == 0){
if(g_list_previous(current_result) == NULL){
return(FALSE);
}
current_result = g_list_previous(current_result);
} else {
if(g_list_next(current_result) == NULL){
return(FALSE);
}
current_result = g_list_next(current_result);
}
if(current_result == NULL)
return(0);
rp = (SEARCH_RESULT *)(current_result->data);
current_book_info = rp->book_info;
if(current_result){
text = ebook_get_text(rp->book_info,
rp->pos_text.page,
rp->pos_text.offset);
show_popup(rp->book_info, text);
free(text);
}
} else if(strcmp(data, "X") == 0){
gtk_widget_destroy(popup);
popup = NULL;
destroy_canvas(popup_area->canvas);
destroy_content_area(popup_area);
}
} else if((event->button == 1) && (event->type == GDK_2BUTTON_PRESS)){
// ダブルクリック
}
return(TRUE);
}
void show_popup(BOOK_INFO *binfo, gchar *text)
{
GdkModifierType mask;
gint pos_x, pos_y;
gint pointer_x, pointer_y;
gint root_x, root_y;
GdkWindow *root_win = NULL;
gint x, y;
gint max_width, max_height;
GdkGC *gc=NULL;
static gint shadow_width = 4, shadow_height = 4;
gint window_width, window_height;
CANVAS *canvas;
DRAW_TEXT l_text;
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *eventbox;
GtkWidget *title_label;
GtkWidget *pixmapwid;
GtkWidget *frame;
GtkWidget *separator;
gboolean redraw=FALSE;
g_return_if_fail(text != NULL);
//無駄にウィンドウサイズが大きくなるのを防ぐ
if(text[strlen(text)-1] == '\n')
text[strlen(text)-1] = '\0';
root_win = gdk_window_foreign_new (GDK_ROOT_WINDOW ());
gdk_window_get_size(root_win, &root_x, &root_y);
if(popup != NULL){
// 既に開いているときにはその位置を使うが、
// 画面からはみ出る時には移動する。
gdk_window_get_position(popup->window, &pos_x, &pos_y);
gtk_widget_destroy(popup);
destroy_canvas(popup_area->canvas);
destroy_content_area(popup_area);
redraw = TRUE;
}
// ポップアップウィンドウの位置を決めるにあたり、
// まずキャンバスのサイズを決める
popup_area = create_content_area(100, 100);
popup_area->show_func = show_in_popup;
popup_area->canvas = create_canvas(window);
popup_area->canvas->content_area = popup_area;
max_width = popup_width - shadow_width - 20;
max_height = popup_height - shadow_height;
simulate_canvas(popup_area->canvas, binfo, text, max_width, max_height);
if(popup_area->canvas->y < max_height)
popup_area->canvas->height = popup_area->canvas->y+10;
if(popup_area->canvas->height < max_height){
window_width = popup_width;
window_height = popup_area->canvas->height + shadow_height;
} else {
window_width = popup_width;
window_height = max_height + shadow_height;
}
if(!redraw){
// ポップアップウィンドウが開いていないときには
// マウスの位置から場所を決定する。
gdk_window_get_pointer(root_win, &pointer_x, &pointer_y, &mask);
pos_x = pointer_x + align_x;
pos_y = pointer_y + align_y;
}
if((pos_x + window_width + align_x + shadow_width) > root_x){
pos_x = root_x - window_width;
}
if(bshow_popup_title) {
if((pos_y + window_height + title_height + align_y + shadow_height) > root_y){
pos_y = root_y - window_height - title_height;
}
} else {
if((pos_y + window_height + align_y + shadow_height) > root_y){
pos_y = root_y - window_height;
}
}
popup = gtk_widget_new (GTK_TYPE_WINDOW,
"type", GTK_WINDOW_TOPLEVEL,
"x", pos_x,
"y", pos_y,
NULL);
gtk_window_set_wmclass(GTK_WINDOW(popup), "Popup", "EBView");
gtk_window_set_policy(GTK_WINDOW(popup),FALSE,FALSE,TRUE);
vbox = gtk_vbox_new(FALSE, 0);
gtk_container_add (GTK_CONTAINER (popup), vbox);
if(bshow_popup_title){
frame = gtk_frame_new(NULL);
gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
hbox = gtk_hbox_new(FALSE, 0);
gtk_container_add( GTK_CONTAINER(frame), hbox);
eventbox = gtk_event_box_new();
gtk_box_pack_start(GTK_BOX(hbox), eventbox, FALSE, FALSE, 2);
gtk_signal_connect( GTK_OBJECT(eventbox),"button_press_event",
(GtkSignalFunc)title_click_event, (gpointer)"<");
pixmapwid = gtk_pixmap_new (small_left_pixmap, small_left_mask);
gtk_container_add( GTK_CONTAINER(eventbox), pixmapwid);
separator = gtk_vseparator_new();
gtk_box_pack_start(GTK_BOX(hbox), separator, FALSE, FALSE, 0);
title_label = gtk_label_new("x of x");
gtk_box_pack_start(GTK_BOX(hbox), title_label, TRUE, TRUE, 0);
separator = gtk_vseparator_new();
gtk_box_pack_start(GTK_BOX(hbox), separator, FALSE, FALSE, 0);
eventbox = gtk_event_box_new();
gtk_box_pack_end(GTK_BOX(hbox), eventbox, FALSE, FALSE, 2);
gtk_signal_connect( GTK_OBJECT(eventbox),"button_press_event",
(GtkSignalFunc)title_click_event, (gpointer)"X");
pixmapwid = gtk_pixmap_new (small_close_pixmap, small_close_mask);
gtk_container_add( GTK_CONTAINER(eventbox), pixmapwid);
separator = gtk_vseparator_new();
gtk_box_pack_end(GTK_BOX(hbox), separator, FALSE, FALSE, 0);
eventbox = gtk_event_box_new();
gtk_box_pack_end(GTK_BOX(hbox), eventbox, FALSE, FALSE, 2);
gtk_signal_connect( GTK_OBJECT(eventbox),"button_press_event",
(GtkSignalFunc)title_click_event, (gpointer)">");
pixmapwid = gtk_pixmap_new (small_right_pixmap, small_right_mask);
gtk_container_add( GTK_CONTAINER(eventbox), pixmapwid);
}
popup_scroll = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (popup_scroll),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
popup_viewport = gtk_viewport_new (
gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(popup_scroll)),
gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW(popup_scroll)));
gtk_container_add (GTK_CONTAINER (popup_scroll), popup_viewport);
gtk_box_pack_start(GTK_BOX(vbox), popup_scroll, FALSE, FALSE, 0);
gtk_signal_connect( GTK_OBJECT(popup_area->area),"button_press_event",
(GtkSignalFunc)popup_click_event, NULL);
gtk_signal_connect( GTK_OBJECT(popup),"close_popup",
(GtkSignalFunc)close_popup, NULL);
gtk_viewport_set_shadow_type(GTK_VIEWPORT(popup_viewport),
GTK_SHADOW_ETCHED_OUT);
gtk_widget_realize(popup);
//gdk_window_set_decorations(popup->window, GDK_DECOR_BORDER);
gdk_window_set_decorations(popup->window, 0);
if(bshow_popup_title){
gchar title[256];
sprintf(title, "%d of %d",
g_list_index(search_result, current_result->data) + 1,
g_list_length(search_result));
gtk_label_set_text(GTK_LABEL(title_label), title);
}
clear_content_area(popup_area);
resize_content_area(popup_area, popup_area->canvas->max_width, popup_area->canvas->height);
create_pixmap(popup_area->canvas);
clear_canvas(popup_area->canvas);
fill_canvas(popup_area->canvas);
draw_canvas(popup_area->canvas, binfo, text);
clear_location(popup_area);
gtk_widget_set_usize(popup_viewport,
window_width,
window_height);
gtk_container_add(GTK_CONTAINER(popup_viewport), popup_area->area);
gtk_widget_show_all(popup);
gtk_adjustment_set_value(
gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(popup_scroll)), 0);
}
syntax highlighted by Code2HTML, v. 0.9.1