📄 changedisplay.c
字号:
{ GtkTreeModel *model; GtkTreeIter iter; if (info->current_screen) g_object_unref (info->current_screen); if (gtk_tree_selection_get_selected (selection, &model, &iter)) gtk_tree_model_get (model, &iter, SCREEN_COLUMN_SCREEN, &info->current_screen, -1); else info->current_screen = NULL;}/* This function is used both for creating the "Display" and * "Screen" frames, since they have a similar structure. The * caller hooks up the right context for the value returned * in tree_view, and packs any relevant buttons into button_vbox. */static voidcreate_frame (ChangeDisplayInfo *info, const char *title, GtkWidget **frame, GtkWidget **tree_view, GtkWidget **button_vbox){ GtkTreeSelection *selection; GtkWidget *scrollwin; GtkWidget *hbox; *frame = gtk_frame_new (title); hbox = gtk_hbox_new (FALSE, 8); gtk_container_set_border_width (GTK_CONTAINER (hbox), 8); gtk_container_add (GTK_CONTAINER (*frame), hbox); scrollwin = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrollwin), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrollwin), GTK_SHADOW_IN); gtk_box_pack_start (GTK_BOX (hbox), scrollwin, TRUE, TRUE, 0); *tree_view = gtk_tree_view_new (); gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (*tree_view), FALSE); gtk_container_add (GTK_CONTAINER (scrollwin), *tree_view); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (*tree_view)); gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE); *button_vbox = gtk_vbox_new (FALSE, 5); gtk_box_pack_start (GTK_BOX (hbox), *button_vbox, FALSE, FALSE, 0); if (!info->size_group) info->size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); gtk_size_group_add_widget (GTK_SIZE_GROUP (info->size_group), *button_vbox);}/* If we have a stack of buttons, it often looks better if their contents * are left-aligned, rather than centered. This function creates a button * and left-aligns it contents. */GtkWidget *left_align_button_new (const char *label){ GtkWidget *button = gtk_button_new_with_mnemonic (label); GtkWidget *child = gtk_bin_get_child (GTK_BIN (button)); gtk_misc_set_alignment (GTK_MISC (child), 0., 0.5); return button;}/* Creates the "Display" frame in the main window. */GtkWidget *create_display_frame (ChangeDisplayInfo *info){ GtkWidget *frame; GtkWidget *tree_view; GtkWidget *button_vbox; GtkTreeViewColumn *column; GtkTreeSelection *selection; GtkWidget *button; create_frame (info, "Display", &frame, &tree_view, &button_vbox); button = left_align_button_new ("_Open..."); g_signal_connect (button, "clicked", G_CALLBACK (open_display_cb), info); gtk_box_pack_start (GTK_BOX (button_vbox), button, FALSE, FALSE, 0); button = left_align_button_new ("_Close"); g_signal_connect (button, "clicked", G_CALLBACK (close_display_cb), info); gtk_box_pack_start (GTK_BOX (button_vbox), button, FALSE, FALSE, 0); info->display_model = (GtkTreeModel *)gtk_list_store_new (DISPLAY_NUM_COLUMNS, G_TYPE_STRING, GDK_TYPE_DISPLAY); gtk_tree_view_set_model (GTK_TREE_VIEW (tree_view), info->display_model); column = gtk_tree_view_column_new_with_attributes ("Name", gtk_cell_renderer_text_new (), "text", DISPLAY_COLUMN_NAME, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)); g_signal_connect (selection, "changed", G_CALLBACK (display_changed_cb), info); return frame;}/* Creates the "Screen" frame in the main window. */GtkWidget *create_screen_frame (ChangeDisplayInfo *info){ GtkWidget *frame; GtkWidget *tree_view; GtkWidget *button_vbox; GtkTreeViewColumn *column; create_frame (info, "Screen", &frame, &tree_view, &button_vbox); info->screen_model = (GtkTreeModel *)gtk_list_store_new (SCREEN_NUM_COLUMNS, G_TYPE_INT, GDK_TYPE_SCREEN); gtk_tree_view_set_model (GTK_TREE_VIEW (tree_view), info->screen_model); column = gtk_tree_view_column_new_with_attributes ("Number", gtk_cell_renderer_text_new (), "text", SCREEN_COLUMN_NUMBER, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column); info->screen_selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)); g_signal_connect (info->screen_selection, "changed", G_CALLBACK (screen_changed_cb), info); return frame;}/* Called when one of the currently open displays is closed. * Remove it from our list of displays. */static voiddisplay_closed_cb (GdkDisplay *display, gboolean is_error, ChangeDisplayInfo *info){ GtkTreeIter iter; gboolean valid; for (valid = gtk_tree_model_get_iter_first (info->display_model, &iter); valid; valid = gtk_tree_model_iter_next (info->display_model, &iter)) { GdkDisplay *tmp_display; gtk_tree_model_get (info->display_model, &iter, DISPLAY_COLUMN_DISPLAY, &tmp_display, -1); if (tmp_display == display) { gtk_list_store_remove (GTK_LIST_STORE (info->display_model), &iter); break; } }}/* Adds a new display to our list of displays, and connects * to the "closed" signal so that we can remove it from the * list of displays again. */static voidadd_display (ChangeDisplayInfo *info, GdkDisplay *display){ const gchar *name = gdk_display_get_name (display); GtkTreeIter iter; gtk_list_store_append (GTK_LIST_STORE (info->display_model), &iter); gtk_list_store_set (GTK_LIST_STORE (info->display_model), &iter, DISPLAY_COLUMN_NAME, name, DISPLAY_COLUMN_DISPLAY, display, -1); g_signal_connect (display, "closed", G_CALLBACK (display_closed_cb), info); }/* Called when a new display is opened */static voiddisplay_opened_cb (GdkDisplayManager *manager, GdkDisplay *display, ChangeDisplayInfo *info){ add_display (info, display);}/* Adds all currently open displays to our list of displays, * and set up a signal connection so that we'll be notified * when displays are opened in the future as well. */static voidinitialize_displays (ChangeDisplayInfo *info){ GdkDisplayManager *manager = gdk_display_manager_get (); GSList *displays = gdk_display_manager_list_displays (manager); GSList *tmp_list; for (tmp_list = displays; tmp_list; tmp_list = tmp_list->next) add_display (info, tmp_list->data); g_slist_free (tmp_list); g_signal_connect (manager, "display_opened", G_CALLBACK (display_opened_cb), info);}/* Cleans up when the toplevel is destroyed; we remove the * connections we use to track currently open displays, then * free the ChangeDisplayInfo structure. */static voiddestroy_info (ChangeDisplayInfo *info){ GdkDisplayManager *manager = gdk_display_manager_get (); GSList *displays = gdk_display_manager_list_displays (manager); GSList *tmp_list; g_signal_handlers_disconnect_by_func (manager, display_opened_cb, info); for (tmp_list = displays; tmp_list; tmp_list = tmp_list->next) g_signal_handlers_disconnect_by_func (tmp_list->data, display_closed_cb, info); g_slist_free (tmp_list); g_object_unref (info->size_group); g_object_unref (info->display_model); g_object_unref (info->screen_model); if (info->current_display) g_object_unref (info->current_display); if (info->current_screen) g_object_unref (info->current_screen); g_free (info);}static voiddestroy_cb (GtkObject *object, ChangeDisplayInfo **info){ destroy_info (*info); *info = NULL;}/* Main entry point. If the dialog for this demo doesn't yet exist, creates * it. Otherwise, destroys it. */GtkWidget *do_changedisplay (GtkWidget *do_widget){ static ChangeDisplayInfo *info = NULL; if (!info) { GtkWidget *vbox; GtkWidget *frame; info = g_new0 (ChangeDisplayInfo, 1); info->window = gtk_dialog_new_with_buttons ("Change Screen or display", GTK_WINDOW (do_widget), GTK_DIALOG_NO_SEPARATOR, GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, "Change", GTK_RESPONSE_OK, NULL); gtk_window_set_default_size (GTK_WINDOW (info->window), 300, 400); g_signal_connect (info->window, "response", G_CALLBACK (response_cb), info); g_signal_connect (info->window, "destroy", G_CALLBACK (destroy_cb), &info); vbox = gtk_vbox_new (FALSE, 5); gtk_container_set_border_width (GTK_CONTAINER (vbox), 8); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (info->window)->vbox), vbox, TRUE, TRUE, 0); frame = create_display_frame (info); gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, 0); frame = create_screen_frame (info); gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, 0); initialize_displays (info); gtk_widget_show_all (info->window); return info->window; } else { gtk_widget_destroy (info->window); return NULL; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -