dblclock.c
来自「开发linux应用-用gtk+和gdk开发linux图形用户界面应用--的实例」· C语言 代码 · 共 254 行
C
254 行
/* * Auth: Eric Harlow * File: dblclock.c * Linux application development * * Double buffered clock (no flickering) */#include <math.h>#include <gtk/gtk.h>#include <time.h>/* --- Backing pixmap for drawing area --- */static GdkPixmap *pixmap = NULL;int radius;/* * DrawTickAt * * Draw a tick mark on the clock's face. * pixmap - drawing area * gc - pen * nHour - 1-12, what time to draw the tick mark * cx - width of clock * cy - height of clock */void DrawTickAt (GdkDrawable *pixmap, GdkGC *gc, int nHour, int cx, int cy){ /* --- Convert time to radians. --- */ double dRadians = nHour * 3.14 / 6.0; /* --- Draw line from .95 * rad to 1.0 * rad --- */ gdk_draw_line (pixmap, gc, cx+(int) ((0.95 * radius * sin (dRadians))), cy-(int) ((0.95 * radius * cos (dRadians))), cx+(int) ((1.0 * radius * sin (dRadians))), cy-(int) ((1.0 * radius * cos (dRadians))));}/* * Repaint * * data - widget to repaint */gint Repaint (gpointer data){ GtkWidget* drawing_area = (GtkWidget *) data; GdkRectangle update_rect; int midx, midy; int nHour; float dRadians; time_t now; struct tm *now_tm; /* --- clear pixmap (background image) --- */ gdk_draw_rectangle (pixmap, drawing_area->style->white_gc, TRUE, 0, 0, drawing_area->allocation.width, drawing_area->allocation.height); /* --- Calculate midpoint of clock --- */ midx = drawing_area->allocation.width / 2; midy = drawing_area->allocation.height / 2; /* --- Calculate radius --- */ radius = MIN (midx, midy); /* --- Draw Circle --- */ gdk_draw_arc (pixmap, drawing_area->style->black_gc, 0, 0, 0, midx + midx, midy + midy, 0, 360 * 64); /* --- Draw Tickmarks --- */ for (nHour = 1; nHour <= 12; nHour++) { DrawTickAt (pixmap, drawing_area->style->black_gc, nHour, midx, midy); } /* --- Get Time --- */ time (&now); now_tm = localtime (&now); /* * --- Draw the second hand */ /* --- Get radians from seconds --- */ dRadians = now_tm->tm_sec * 3.14 / 30.0; /* --- Draw seconds --- */ gdk_draw_line (pixmap, drawing_area->style->black_gc, midx, midy, midx + (0.9 * radius * sin (dRadians)), midy - (0.9 * radius * cos (dRadians))); /* * --- Draw the minute */ /* --- Get radians from minutes and seconds --- */ dRadians = (now_tm->tm_min * 3.14 / 30.0) + (3.14 * now_tm->tm_sec / 1800.0); /* --- Draw Minutes --- */ gdk_draw_line (pixmap, drawing_area->style->black_gc, midx, midy, midx+(int) (0.7 * radius * sin (dRadians)), midy-(int) (0.7 * radius * cos (dRadians))); /* * --- Draw the hour hand */ /* --- Calculate hours to the time in radians --- */ dRadians = (now_tm->tm_hour % 12) * 3.14 / 6.0 + (3.14 * now_tm->tm_min / 360.0); /* --- Draw the hour hand --- */ gdk_draw_line (pixmap, drawing_area->style->black_gc, midx, midy, midx + (int) (radius * 0.5 * sin (dRadians)), midy - (int) (radius * 0.5 * cos (dRadians))); /* --- Set the rect up - * The entire pixmap is going to be copied * onto the window so the rect is configured * as the size of the window. */ update_rect.x = 0; update_rect.y = 0; update_rect.width = drawing_area->allocation.width; update_rect.height = drawing_area->allocation.height; /* --- And then draw it (calls expose event) --- */ gtk_widget_draw (drawing_area, &update_rect); return (TRUE);}/* * configure_event * * Create a new backing pixmap of the appropriate size * Of course, this is called whenever the window is * resized. We have to free up things we allocated. */static gint configure_event (GtkWidget *widget, GdkEventConfigure *event){ /* --- Free background if we created it --- */ if (pixmap) { gdk_pixmap_unref (pixmap); } /* --- Create a new pixmap with new size --- */ pixmap = gdk_pixmap_new (widget->window, widget->allocation.width, widget->allocation.height, -1); return TRUE;}/* * expose_event * * When the window is exposed to the viewer or * the gdk_widget_draw routine is called, this * routine is called. Copies the background pixmap * to the window. */gint expose_event (GtkWidget *widget, GdkEventExpose *event){ /* --- Copy pixmap to the window --- */ gdk_draw_pixmap (widget->window, widget->style->fg_gc[GTK_WIDGET_STATE (widget)], pixmap, event->area.x, event->area.y, event->area.x, event->area.y, event->area.width, event->area.height); return FALSE;}/* * quit * * Get out of the application */void quit (){ gtk_exit (0);}/* * main * * Program begins here. */ int main (int argc, char *argv[]){ GtkWidget *window; GtkWidget *drawing_area; GtkWidget *vbox; gtk_init (&argc, &argv); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); vbox = gtk_hbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (window), vbox); gtk_widget_show (vbox); gtk_signal_connect (GTK_OBJECT (window), "destroy", GTK_SIGNAL_FUNC (quit), NULL); /* --- Create the drawing area --- */ drawing_area = gtk_drawing_area_new (); gtk_drawing_area_size (GTK_DRAWING_AREA (drawing_area), 200, 200); gtk_box_pack_start (GTK_BOX (vbox), drawing_area, TRUE, TRUE, 0); gtk_widget_show (drawing_area); /* --- Signals used to handle backing pixmap --- */ gtk_signal_connect (GTK_OBJECT (drawing_area), "expose_event", (GtkSignalFunc) expose_event, NULL); gtk_signal_connect (GTK_OBJECT(drawing_area),"configure_event", (GtkSignalFunc) configure_event, NULL); /* --- Show the window --- */ gtk_widget_show (window); /* --- Repaint every second --- */ gtk_timeout_add (1000, Repaint, drawing_area); /* --- Call gtk-main loop --- */ gtk_main (); return 0;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?