📄 gtkentry.c
字号:
voidgtk_entry_set_visibility (GtkEntry *entry, gboolean visible){ g_return_if_fail (entry != NULL); g_return_if_fail (GTK_IS_ENTRY (entry)); entry->visible = visible ? TRUE : FALSE; GTK_EDITABLE (entry)->visible = visible ? TRUE : FALSE; gtk_entry_recompute_offsets (entry); gtk_widget_queue_draw (GTK_WIDGET (entry));}voidgtk_entry_set_editable(GtkEntry *entry, gboolean editable){ g_return_if_fail (entry != NULL); g_return_if_fail (GTK_IS_ENTRY (entry)); gtk_editable_set_editable (GTK_EDITABLE (entry), editable);}gchar*gtk_entry_get_text (GtkEntry *entry){ g_return_val_if_fail (entry != NULL, NULL); g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL); if (!entry->text_mb_dirty) return entry->text_mb; if (entry->text_mb) g_free(entry->text_mb); if (!entry->text) { entry->text_mb = g_new(gchar, 1); entry->text_mb[0] = 0; } else { entry->text_mb = gtk_entry_get_chars(GTK_EDITABLE(entry), 0, -1); } entry->text_mb_dirty = 0; return entry->text_mb;}static voidgtk_entry_finalize (GtkObject *object){ GtkEntry *entry; g_return_if_fail (object != NULL); g_return_if_fail (GTK_IS_ENTRY (object)); entry = GTK_ENTRY (object); if (entry->timer) gtk_timeout_remove (entry->timer); entry->text_size = 0; if (entry->text) g_free (entry->text); if (entry->char_offset) g_free (entry->char_offset); entry->text = NULL; if (entry->text_mb) g_free (entry->text_mb); entry->text_mb = NULL; if (entry->backing_pixmap) gdk_pixmap_unref (entry->backing_pixmap); (* GTK_OBJECT_CLASS (parent_class)->finalize) (object);}static voidgtk_entry_realize (GtkWidget *widget){ GtkEntry *entry; GtkEditable *editable; GtkRequisition requisition; GdkWindowAttr attributes; gint attributes_mask; g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_ENTRY (widget)); GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); entry = GTK_ENTRY (widget); editable = GTK_EDITABLE (widget); gtk_widget_get_child_requisition (widget, &requisition); attributes.window_type = GDK_WINDOW_CHILD; attributes.x = widget->allocation.x; attributes.y = widget->allocation.y + (widget->allocation.height - requisition.height) / 2; attributes.width = widget->allocation.width; attributes.height = requisition.height; attributes.wclass = GDK_INPUT_OUTPUT; attributes.visual = gtk_widget_get_visual (widget); attributes.colormap = gtk_widget_get_colormap (widget); attributes.event_mask = gtk_widget_get_events (widget); attributes.event_mask |= (GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_BUTTON1_MOTION_MASK | GDK_BUTTON3_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_KEY_PRESS_MASK); attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask); gdk_window_set_user_data (widget->window, entry); attributes.x = widget->style->klass->xthickness; attributes.y = widget->style->klass->ythickness; attributes.width = widget->allocation.width - attributes.x * 2; attributes.height = requisition.height - attributes.y * 2; attributes.cursor = entry->cursor = gdk_cursor_new (GDK_XTERM); attributes_mask |= GDK_WA_CURSOR; entry->text_area = gdk_window_new (widget->window, &attributes, attributes_mask); gdk_window_set_user_data (entry->text_area, entry); widget->style = gtk_style_attach (widget->style, widget->window); gdk_window_set_background (widget->window, &widget->style->base[GTK_WIDGET_STATE (widget)]); gdk_window_set_background (entry->text_area, &widget->style->base[GTK_WIDGET_STATE (widget)]);#ifdef USE_XIM if (gdk_im_ready () && (editable->ic_attr = gdk_ic_attr_new ()) != NULL) { gint width, height; GdkEventMask mask; GdkColormap *colormap; GdkICAttr *attr = editable->ic_attr; GdkICAttributesType attrmask = GDK_IC_ALL_REQ; GdkIMStyle style; GdkIMStyle supported_style = GDK_IM_PREEDIT_NONE | GDK_IM_PREEDIT_NOTHING | GDK_IM_PREEDIT_POSITION | GDK_IM_STATUS_NONE | GDK_IM_STATUS_NOTHING; if (widget->style && widget->style->font->type != GDK_FONT_FONTSET) supported_style &= ~GDK_IM_PREEDIT_POSITION; attr->style = style = gdk_im_decide_style (supported_style); attr->client_window = entry->text_area; if ((colormap = gtk_widget_get_colormap (widget)) != gtk_widget_get_default_colormap ()) { attrmask |= GDK_IC_PREEDIT_COLORMAP; attr->preedit_colormap = colormap; } attrmask |= GDK_IC_PREEDIT_FOREGROUND; attrmask |= GDK_IC_PREEDIT_BACKGROUND; attr->preedit_foreground = widget->style->fg[GTK_STATE_NORMAL]; attr->preedit_background = widget->style->base[GTK_STATE_NORMAL]; switch (style & GDK_IM_PREEDIT_MASK) { case GDK_IM_PREEDIT_POSITION: if (widget->style && widget->style->font->type != GDK_FONT_FONTSET) { g_warning ("over-the-spot style requires fontset"); break; } gdk_window_get_size (entry->text_area, &width, &height); attrmask |= GDK_IC_PREEDIT_POSITION_REQ; attr->spot_location.x = 0; attr->spot_location.y = height; attr->preedit_area.x = 0; attr->preedit_area.y = 0; attr->preedit_area.width = width; attr->preedit_area.height = height; attr->preedit_fontset = widget->style->font; break; } editable->ic = gdk_ic_new (attr, attrmask); if (editable->ic == NULL) g_warning ("Can't create input context."); else { mask = gdk_window_get_events (entry->text_area); mask |= gdk_ic_get_events (editable->ic); gdk_window_set_events (entry->text_area, mask); if (GTK_WIDGET_HAS_FOCUS(widget)) gdk_im_begin (editable->ic, entry->text_area); } }#endif gdk_window_show (entry->text_area); if (editable->selection_start_pos != editable->selection_end_pos) gtk_editable_claim_selection (editable, TRUE, GDK_CURRENT_TIME); gtk_entry_recompute_offsets (entry);}static voidgtk_entry_unrealize (GtkWidget *widget){ GtkEntry *entry; g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_ENTRY (widget)); entry = GTK_ENTRY (widget);#ifdef USE_XIM if (GTK_EDITABLE (widget)->ic) { gdk_ic_destroy (GTK_EDITABLE (widget)->ic); GTK_EDITABLE (widget)->ic = NULL; } if (GTK_EDITABLE (widget)->ic_attr) { gdk_ic_attr_destroy (GTK_EDITABLE (widget)->ic_attr); GTK_EDITABLE (widget)->ic_attr = NULL; }#endif if (entry->text_area) { gdk_window_set_user_data (entry->text_area, NULL); gdk_window_destroy (entry->text_area); entry->text_area = NULL; gdk_cursor_destroy (entry->cursor); entry->cursor = NULL; } if (GTK_WIDGET_CLASS (parent_class)->unrealize) (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);}static voidgtk_entry_draw_focus (GtkWidget *widget){ gint width, height; gint x, y; g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_ENTRY (widget)); if (GTK_WIDGET_DRAWABLE (widget)) { x = 0; y = 0; gdk_window_get_size (widget->window, &width, &height); if (GTK_WIDGET_HAS_FOCUS (widget)) { x += 1; y += 1; width -= 2; height -= 2; } gtk_paint_shadow (widget->style, widget->window, GTK_STATE_NORMAL, GTK_SHADOW_IN, NULL, widget, "entry", x, y, width, height); if (GTK_WIDGET_HAS_FOCUS (widget)) { gdk_window_get_size (widget->window, &width, &height); gtk_paint_focus (widget->style, widget->window, NULL, widget, "entry", 0, 0, width - 1, height - 1); } if (GTK_EDITABLE (widget)->editable) gtk_entry_draw_cursor (GTK_ENTRY (widget)); }}static voidgtk_entry_size_request (GtkWidget *widget, GtkRequisition *requisition){ g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_ENTRY (widget)); g_return_if_fail (requisition != NULL); requisition->width = MIN_ENTRY_WIDTH + (widget->style->klass->xthickness + INNER_BORDER) * 2; requisition->height = (widget->style->font->ascent + widget->style->font->descent + (widget->style->klass->ythickness + INNER_BORDER) * 2);}static voidgtk_entry_size_allocate (GtkWidget *widget, GtkAllocation *allocation){ GtkEntry *entry; GtkEditable *editable; g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_ENTRY (widget)); g_return_if_fail (allocation != NULL); widget->allocation = *allocation; entry = GTK_ENTRY (widget); editable = GTK_EDITABLE (widget); if (GTK_WIDGET_REALIZED (widget)) { /* We call gtk_widget_get_child_requisition, since we want (for * backwards compatibility reasons) the realization here to * be affected by the usize of the entry, if set */ GtkRequisition requisition; gtk_widget_get_child_requisition (widget, &requisition); gdk_window_move_resize (widget->window, allocation->x, allocation->y + (allocation->height - requisition.height) / 2, allocation->width, requisition.height); gdk_window_move_resize (entry->text_area, widget->style->klass->xthickness, widget->style->klass->ythickness, allocation->width - widget->style->klass->xthickness * 2, requisition.height - widget->style->klass->ythickness * 2); /* And make sure the cursor is on screen */ entry_adjust_scroll (entry); #ifdef USE_XIM if (editable->ic && (gdk_ic_get_style (editable->ic) & GDK_IM_PREEDIT_POSITION)) { gint width, height; gdk_window_get_size (entry->text_area, &width, &height); editable->ic_attr->preedit_area.width = width; editable->ic_attr->preedit_area.height = height; gdk_ic_set_attr (editable->ic, editable->ic_attr, GDK_IC_PREEDIT_AREA); }#endif }}static voidgtk_entry_draw (GtkWidget *widget, GdkRectangle *area){ g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_ENTRY (widget)); g_return_if_fail (area != NULL); if (GTK_WIDGET_DRAWABLE (widget)) { gtk_widget_draw_focus (widget); gtk_entry_draw_text (GTK_ENTRY (widget)); }}static gintgtk_entry_expose (GtkWidget *widget, GdkEventExpose *event){ GtkEntry *entry; g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_ENTRY (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); entry = GTK_ENTRY (widget); if (widget->window == event->window) gtk_widget_draw_focus (widget); else if (entry->text_area == event->window) gtk_entry_draw_text (GTK_ENTRY (widget)); return FALSE;}static gintgtk_entry_button_press (GtkWidget *widget, GdkEventButton *event){ GtkEntry *entry; GtkEditable *editable; gint tmp_pos; g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_ENTRY (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); if (ctext_atom == GDK_NONE) ctext_atom = gdk_atom_intern ("COMPOUND_TEXT", FALSE); entry = GTK_ENTRY (widget); editable = GTK_EDITABLE (widget); if (entry->button && (event->button != entry->button)) return FALSE; entry->button = event->button; if (!GTK_WIDGET_HAS_FOCUS (widget)) gtk_widget_grab_focus (widget); if (event->button == 1) { switch (event->type) { case GDK_BUTTON_PRESS: gtk_grab_add (widget); tmp_pos = gtk_entry_position (entry, event->x + entry->scroll_offset); /* Set it now, so we display things right. We'll unset it * later if things don't work out */ editable->has_selection = TRUE; gtk_entry_set_selection (editable, tmp_pos, tmp_pos); editable->current_pos = editable->selection_start_pos; break; case GDK_2BUTTON_PRESS: gtk_select_word (entry, event->time); break; case GDK_3BUTTON_PRESS: gtk_select_line (entry, event->time); break; default: break; } } else if (event->type == GDK_BUTTON_PRESS) { if ((event->button == 2) && editable->editable) { if (editable->selection_start_pos == editable->selection_end_pos || editable->has_selection) editable->current_pos = gtk_entry_position (entry, event->x + entry->scroll_offset); gtk_selection_convert (widget, GDK_SELECTION_PRIMARY, ctext_atom, event->time); } else { gtk_grab_add (widget); tmp_pos = gtk_entry_position (entry, event->x + entry->scroll_offset); gtk_entry_set_selection (editable, tmp_pos, tmp_pos);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -