📄 panel.c
字号:
/* GKrellM| Copyright (C) 1999-2006 Bill Wilson|| Author: Bill Wilson billw@gkrellm.net| Latest versions might be found at: http://gkrellm.net|| This program is free software which I release under the GNU General Public| License. You may redistribute and/or modify this program under the terms| of that 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. Version 2 is in the| COPYRIGHT file in the top level directory of this distribution.| | To get a copy of the GNU General Puplic License, write to the Free Software| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/#include "gkrellm.h"#include "gkrellm-private.h"static GList *panel_list;GList *gkrellm_get_panel_list(void) { return panel_list; }voidgkrellm_panel_configure_add_height(GkrellmPanel *p, gint h) { if (!p) return; p->h_configure += h; }voidgkrellm_panel_configure_set_height(GkrellmPanel *p, gint h) { if (!p) return; p->h_configure = h; }gintgkrellm_panel_configure_get_height(GkrellmPanel *p) { if (!p) return 0; return p->h_configure; }static voidsetup_panel_style(GkrellmPanel *p, GkrellmStyle *style) { GkrellmLabel *lbl = p->label; p->style = style; if (!style) return; lbl->position = style->label_position; p->transparency = style->transparency; p->scroll_text_cache_off = style->scroll_text_cache_off; _GK.any_transparency |= p->transparency; if (!p->textstyle) { p->textstyle = gkrellm_textstyle_new0(); p->textstyle->internal = TRUE; } if (p->textstyle->internal) { *(p->textstyle) = style->label_tsA; p->textstyle->internal = TRUE; p->textstyle->font = *(style->label_tsA.font_seed); } }voidgkrellm_panel_label_get_position(GkrellmStyle *style, gint *x_position, gint *y_off) { if (!style) return; if (x_position) *x_position = style->label_position; if (y_off) *y_off = style->label_yoff; } /* Calculate panel height required for given border, label height, | krell heights, and decal heights. Also calculate label extents | and load all this info into a GkrellmLabel structure. | After panel height is calculated, calling routine may want to adjust | krell or decal y offsets for centering. */voidgkrellm_panel_configure(GkrellmPanel *p, gchar *string, GkrellmStyle *style) { GList *list; GkrellmKrell *k; GkrellmDecal *d; GkrellmLabel *lbl; GkrellmTextstyle *ts = NULL; gint y, h_panel, h, baseline; gint top_margin = 0, bottom_margin = 0; if (!p) return; p->style = style; lbl = p->label; lbl->position = GKRELLM_LABEL_CENTER; setup_panel_style(p, style); gkrellm_get_top_bottom_margins(style, &top_margin, &bottom_margin); ts = p->textstyle; if (string) { if (g_utf8_validate(string, -1, NULL)) gkrellm_dup_string(&lbl->string, string); else lbl->string = g_locale_to_utf8(string, -1, NULL, NULL, NULL); } else gkrellm_dup_string(&lbl->string, string); if (lbl->string && ts && lbl->position >= 0) gkrellm_text_extents(ts->font, string, strlen(string), &lbl->width, &lbl->height, &baseline, NULL); else { lbl->width = 0; lbl->height = 0; baseline = 0; } if (style && style->label_yoff > 0) h_panel = style->label_yoff + bottom_margin; else h_panel = top_margin + bottom_margin; h_panel += lbl->height + (ts ? ts->effect : 0); /* If krell_yoff is -1, then in gkrellm_create_krell() k->y0 was put | at the top margin. If krell_yoff is < -1, then here I will bottom | justify the krell (so must go through krell list twice). | GkrellmDecals are assumed to fit inside of margins (unless they are | overlays). Caller must subtract off bottom_margin if this is not so. */ for (list = p->decal_list; list; list = list->next) { d = (GkrellmDecal *) list->data; if (d->flags & DF_OVERLAY_PIXMAPS) continue; h = d->y + d->h + bottom_margin; if (h > h_panel) h_panel = h; } for (list = p->krell_list; list; list = list->next) { k = (GkrellmKrell *) list->data; if (k->y0 == -2) /* Will bottom justify */ y = 0; else if (k->y0 == -3) /* Will bottom margin justify */ y = top_margin; else y = k->y0; h = y + k->h_frame; if (k->flags & KRELL_FLAG_BOTTOM_MARGIN) h += bottom_margin; if (h > h_panel) h_panel = h; } for (list = p->krell_list; list; list = list->next) { k = (GkrellmKrell *) list->data; if (k->y0 < 0) { k->y0 = h_panel - k->h_frame; /* Bottom justify */ if (k->flags & KRELL_FLAG_BOTTOM_MARGIN) /* or y0 == -3 */ k->y0 -= bottom_margin; } } if (h_panel <= 0) h_panel = 1; if (style && style->label_yoff > 0) lbl->y_panel = style->label_yoff - (baseline - lbl->height); else lbl->y_panel = top_margin - (baseline - lbl->height); p->h_configure = h_panel; }static voiddraw_panel_label(GkrellmPanel *p, gboolean to_bg) { GkrellmLabel *lbl = p->label; GkrellmTextstyle *ts = p->textstyle; GkrellmMargin *m; gchar *s; gint xdst; if ( lbl && ts && ((s = lbl->string) != NULL) && lbl->position >= 0 ) { m = gkrellm_get_style_margins(p->style); lbl->width = gkrellm_gdk_string_width(ts->font, s) + ts->effect; xdst = gkrellm_label_x_position(lbl->position, p->w, lbl->width, m->left); lbl->x_panel = xdst; gkrellm_draw_string(p->pixmap, ts, xdst, lbl->y_panel, s); if (to_bg) gkrellm_draw_string(p->bg_pixmap, ts, xdst, lbl->y_panel, s); } }static voiddraw_panel(GkrellmPanel *p, gint to_screen) { if (!gkrellm_winop_draw_rootpixmap_onto_transparent_panel(p)) gdk_draw_drawable(p->bg_pixmap, _GK.draw1_GC, p->bg_clean_pixmap, 0, 0, 0, 0, p->w, p->h); gdk_draw_drawable(p->pixmap, _GK.draw1_GC, p->bg_pixmap, 0, 0, 0, 0, p->w, p->h); draw_panel_label(p, TRUE); gdk_draw_drawable(p->bg_text_layer_pixmap, _GK.draw1_GC, p->bg_pixmap, 0, 0, 0, 0, p->w, p->h); if (p->drawing_area->window && to_screen) { gdk_draw_drawable(p->drawing_area->window, _GK.draw1_GC, p->pixmap, 0, 0, 0, 0, p->w, p->h); gkrellm_draw_panel_layers_force(p); } }voidgkrellm_panel_label_on_top_of_decals(GkrellmPanel *p, gboolean mode) { if (p) p->label_on_top_of_decals = mode; }voidgkrellm_draw_panel_label(GkrellmPanel *p) { if (p) draw_panel(p, TRUE); }voidgkrellm_panel_destroy(GkrellmPanel *p) { if (!p) return; gkrellm_reset_panel_alerts(p); gkrellm_destroy_krell_list(p); gkrellm_destroy_decal_list(p); /* Also destroys buttons */ if (p->button_list || p->button_signals_connected) fprintf(stderr, "gkrellm_destroy_panel: button_list=%p connected=%d\n", p->button_list, p->button_signals_connected); if (p->label) { if (p->label->string) g_free(p->label->string); g_free(p->label); } if (p->layout) g_object_unref(G_OBJECT(p->layout)); if (p->textstyle && p->textstyle->internal) g_free(p->textstyle); if (p->pixmap) g_object_unref(G_OBJECT(p->pixmap)); if (p->bg_pixmap) g_object_unref(G_OBJECT(p->bg_pixmap)); if (p->bg_text_layer_pixmap) g_object_unref(G_OBJECT(p->bg_text_layer_pixmap)); if (p->bg_clean_pixmap) g_object_unref(G_OBJECT(p->bg_clean_pixmap)); if (p->bg_mask) g_object_unref(G_OBJECT(p->bg_mask)); if (p->hbox) gtk_widget_destroy(p->hbox); panel_list = g_list_remove(panel_list, p); if (p->shown) gkrellm_monitor_height_adjust(- p->h); g_free(p); gkrellm_pack_side_frames(); }voidgkrellm_panel_bg_piximage_override(GkrellmPanel *p, GkrellmPiximage *bg_piximage) { if (!p || !bg_piximage) return; p->bg_piximage = bg_piximage; p->bg_piximage_override = TRUE; }voidgkrellm_panel_keep_lists(GkrellmPanel *p, gboolean keep) { if (p) p->keep_lists = keep; }#if 0static gbooleancb_panel_map_event(GtkWidget *widget, GdkEvent *event, GkrellmPanel *p) { gdk_window_get_position(p->drawing_area->window, NULL, &p->y_mapped); if (_GK.frame_left_panel_overlap > 0 || _GK.frame_right_panel_overlap > 0) _GK.need_frame_packing = TRUE; return FALSE; }#endifstatic gbooleancb_panel_size_allocate(GtkWidget *widget, GtkAllocation *size, GkrellmPanel *p) { gdk_window_get_position(p->drawing_area->window, NULL, &p->y_mapped); if (_GK.frame_left_panel_overlap > 0 || _GK.frame_right_panel_overlap > 0) _GK.need_frame_packing = TRUE; return FALSE; }voidgkrellm_panel_create(GtkWidget *vbox, GkrellmMonitor *mon, GkrellmPanel *p) { GtkWidget *hbox; GkrellmPiximage piximage; GtkWidget *top_win = gkrellm_get_top_window(); if (!vbox || !mon || !p) return; p->monitor = (gpointer) mon; if (!p->style) /* gkrellm_panel_configure() may not have been called. */ setup_panel_style(p, mon->privat->panel_style); if (!p->bg_piximage_override) { if (mon->privat->style_type == CHART_PANEL_TYPE) p->bg_piximage = gkrellm_bg_panel_piximage(mon->privat->style_id); else p->bg_piximage = gkrellm_bg_meter_piximage(mon->privat->style_id); } p->bg_piximage_override = FALSE; /* If not being called from rebuild or after a panel destroy, then panel | still has a height that must be accounted for. */ if (p->h && p->shown) gkrellm_monitor_height_adjust(- p->h); p->h = p->h_configure; p->w = _GK.chart_width; if (p->hbox == NULL) { hbox = gtk_hbox_new(FALSE, 0); gtk_container_add (GTK_CONTAINER(vbox), hbox); p->hbox = hbox; p->drawing_area = gtk_drawing_area_new(); p->layout = gtk_widget_create_pango_layout(top_win, NULL); gtk_widget_set_events (p->drawing_area, GDK_EXPOSURE_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_ENTER_NOTIFY_MASK | GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK); gtk_box_pack_start(GTK_BOX(p->hbox), p->drawing_area, FALSE, FALSE, 0); gtk_widget_show(p->drawing_area); gtk_widget_show(hbox); p->shown = TRUE; gtk_widget_realize(hbox); gtk_widget_realize(p->drawing_area); panel_list = g_list_append(panel_list, p); p->y_mapped = -1; g_signal_connect(G_OBJECT (p->drawing_area), "size_allocate", G_CALLBACK(cb_panel_size_allocate), p); } gtk_widget_set_size_request(p->drawing_area, p->w, p->h); if (_GK.frame_left_panel_overlap > 0 || _GK.frame_right_panel_overlap > 0) { piximage.pixbuf = gdk_pixbuf_new_subpixbuf(p->bg_piximage->pixbuf, _GK.frame_left_panel_overlap, 0, gdk_pixbuf_get_width(p->bg_piximage->pixbuf) - _GK.frame_left_panel_overlap - _GK.frame_right_panel_overlap, gdk_pixbuf_get_height(p->bg_piximage->pixbuf)); piximage.border = p->bg_piximage->border; gkrellm_border_adjust(&piximage.border, -_GK.frame_left_panel_overlap, -_GK.frame_right_panel_overlap, 0, 0);// gkrellm_scale_piximage_to_pixmap(&piximage, &p->bg_clean_pixmap,// &p->bg_mask, p->w, p->h); gkrellm_scale_theme_background(&piximage, &p->bg_clean_pixmap, &p->bg_mask, p->w, p->h); g_object_unref(G_OBJECT(piximage.pixbuf)); } else gkrellm_scale_theme_background(p->bg_piximage, &p->bg_clean_pixmap, &p->bg_mask, p->w, p->h);// gkrellm_scale_piximage_to_pixmap(p->bg_piximage, &p->bg_clean_pixmap,// &p->bg_mask, p->w, p->h); if (p->bg_text_layer_pixmap) g_object_unref(G_OBJECT(p->bg_text_layer_pixmap)); p->bg_text_layer_pixmap = gdk_pixmap_new(top_win->window, p->w, p->h, -1); if (p->bg_pixmap) g_object_unref(G_OBJECT(p->bg_pixmap)); p->bg_pixmap = gdk_pixmap_new(top_win->window, p->w, p->h, -1); if (p->pixmap) g_object_unref(G_OBJECT(p->pixmap)); p->pixmap = gdk_pixmap_new(top_win->window, p->w, p->h, -1); if (p->shown) { gkrellm_monitor_height_adjust(p->h); gkrellm_pack_side_frames(); } p->need_decal_overlap_check = TRUE; draw_panel(p, FALSE); gkrellm_panel_button_signals_connect(p); }voidgkrellm_panel_hide(GkrellmPanel *p) { if (!p || !p->shown) return; gtk_widget_hide(p->hbox); p->shown = FALSE; gkrellm_monitor_height_adjust(- p->h); gkrellm_pack_side_frames(); }voidgkrellm_panel_show(GkrellmPanel *p) { if (!p || p->shown)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -