/*
* This file is a part of hildon
*
* Copyright (C) 2008, 2009 Nokia Corporation, all rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser Public License as published by
* the Free Software Foundation; version 2 of the license.
*
* 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 Lesser Public License for more details.
*
*/
/**
* SECTION:hildon-text-view
* @short_description: Text view within the Hildon framework.
*
* #HildonTextView is a text view derived from the #GtkTextView widget
* but with a slightly different appearance designed for the Hildon
* 2.2 framework.
*
* Text views in Hildon 2.2 can have a placeholder text, set with
* hildon_gtk_text_view_set_placeholder_text(). This text will be
* shown if the text view is empty and doesn't have the input focus,
* but it's otherwise ignored. Thus, calls to
* gtk_text_view_get_buffer() will never return the placeholder text,
* not even when it's being displayed.
*
*
* Creating a HildonTextView with a placeholder
*
* GtkWidget *
* create_text_view (void)
* {
* GtkWidget *text_view;
*
* text_view = hildon_text_view_new ();
* hildon_gtk_text_view_set_placeholder_text (GTK_TEXT_VIEW (text_view),
* "Type some text here");
*
* return text_view;
* }
*
*
*/
#include "hildon-text-view.h"
#include
#define HILDON_TEXT_VIEW_DRAG_THRESHOLD 16.0
G_DEFINE_TYPE (HildonTextView, hildon_text_view, GTK_TYPE_TEXT_VIEW);
#define HILDON_TEXT_VIEW_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
HILDON_TYPE_TEXT_VIEW, HildonTextViewPrivate));
typedef struct _HildonTextViewPrivate HildonTextViewPrivate;
struct _HildonTextViewPrivate
{
gdouble x; /* tap x position */
gdouble y; /* tap y position */
gboolean selection_movement; /* selection in progress */
};
/**
* hildon_text_view_new:
*
* Creates a new text view.
*
* Returns: a new #HildonTextView
*
* Since: 2.2
*/
GtkWidget *
hildon_text_view_new (void)
{
GtkWidget *entry = g_object_new (HILDON_TYPE_TEXT_VIEW, NULL);
return entry;
}
static gint
hildon_text_view_button_press_event (GtkWidget *widget,
GdkEventButton *event)
{
HildonTextViewPrivate *priv = HILDON_TEXT_VIEW_GET_PRIVATE (widget);
gtk_widget_grab_focus (widget);
if (GTK_TEXT_VIEW (widget)->editable)
{
GTK_TEXT_VIEW (widget)->need_im_reset = TRUE;
return TRUE;
}
if (event->button == 1 && event->type == GDK_BUTTON_PRESS) {
priv->x = event->x;
priv->y = event->y;
if (event->state & GDK_SHIFT_MASK) {
GtkTextBuffer *buffer;
GtkTextWindowType window_type;
GtkTextIter iter;
gint x, y;
GtkTextView *text_view = GTK_TEXT_VIEW (widget);
priv->selection_movement = TRUE;
window_type = gtk_text_view_get_window_type (text_view,
event->window);
gtk_text_view_window_to_buffer_coords (text_view,
window_type,
event->x, event->y,
&x, &y);
gtk_text_view_get_iter_at_location (text_view, &iter, x, y);
buffer = gtk_text_view_get_buffer (text_view);
if (gtk_text_buffer_get_char_count (buffer)) {
gtk_text_buffer_place_cursor (buffer, &iter);
}
return GTK_WIDGET_CLASS (hildon_text_view_parent_class)->
button_press_event (widget, event);
}
return TRUE;
}
return FALSE;
}
static gint
hildon_text_view_button_release_event (GtkWidget *widget,
GdkEventButton *event)
{
GtkTextView *text_view = GTK_TEXT_VIEW (widget);
HildonTextViewPrivate *priv = HILDON_TEXT_VIEW_GET_PRIVATE (widget);
GtkTextIter iter;
gint x, y;
if (text_view->editable)
{
text_view->need_im_reset = TRUE;
return TRUE;
}
if (event->button == 1 && event->type == GDK_BUTTON_RELEASE &&
!priv->selection_movement) {
if (fabs (priv->x - event->x) < HILDON_TEXT_VIEW_DRAG_THRESHOLD &&
fabs (priv->y - event->y) < HILDON_TEXT_VIEW_DRAG_THRESHOLD) {
GtkTextWindowType window_type;
GtkTextBuffer *buffer;
window_type = gtk_text_view_get_window_type (text_view, event->window);
gtk_text_view_window_to_buffer_coords (text_view,
window_type,
event->x, event->y,
&x, &y);
gtk_text_view_get_iter_at_location (text_view, &iter, x, y);
buffer = gtk_text_view_get_buffer (text_view);
if (gtk_text_buffer_get_char_count (buffer))
gtk_text_buffer_place_cursor (buffer, &iter);
gtk_widget_grab_focus (GTK_WIDGET (text_view));
return TRUE;
}
}
if (priv->selection_movement) {
gboolean result;
result = GTK_WIDGET_CLASS (hildon_text_view_parent_class)->
button_release_event (widget, event);
if (result) {
priv->selection_movement = FALSE;
}
return result;
}
return FALSE;
}
static void
hildon_text_view_class_init (HildonTextViewClass *klass)
{
GtkWidgetClass *widget_class = (GtkWidgetClass *)klass;
widget_class->motion_notify_event = NULL;
widget_class->button_press_event = hildon_text_view_button_press_event;
widget_class->button_release_event = hildon_text_view_button_release_event;
g_type_class_add_private (klass, sizeof (HildonTextViewPrivate));
}
static void
hildon_text_view_init (HildonTextView *self)
{
HildonTextViewPrivate *priv = HILDON_TEXT_VIEW_GET_PRIVATE (self);
priv->selection_movement = FALSE;
}