⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vivi_movie_list.c

📁 Swfdec is a decoder/renderer for Macromedia Flash animations. The decoding and rendering engine is
💻 C
字号:
/* Swfdec * Copyright (C) 2007 Benjamin Otte <otte@gnome.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. *  * This library 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 General Public License for more details. *  * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, to_string to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor,  * Boston, MA  02110-1301  USA */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <gtk/gtk.h>#include <libswfdec/swfdec_movie.h>#include <libswfdec/swfdec_player_internal.h>#include "vivi_movie_list.h"/*** GTK_TREE_MODEL ***/#if 0#  define REPORT g_print ("%s\n", G_STRFUNC)#else#  define REPORT #endifstatic GtkTreeModelFlags vivi_movie_list_get_flags (GtkTreeModel *tree_model){  REPORT;  return 0;}static gintvivi_movie_list_get_n_columns (GtkTreeModel *tree_model){  REPORT;  return VIVI_MOVIE_LIST_N_COLUMNS;}static GTypevivi_movie_list_get_column_type (GtkTreeModel *tree_model, gint index_){  REPORT;  switch (index_) {    case VIVI_MOVIE_LIST_COLUMN_MOVIE:      return G_TYPE_POINTER;    case VIVI_MOVIE_LIST_COLUMN_NAME:      return G_TYPE_STRING;    case VIVI_MOVIE_LIST_COLUMN_DEPTH:      return G_TYPE_INT;    case VIVI_MOVIE_LIST_COLUMN_TYPE:      return G_TYPE_STRING;    default:      break;  }  g_assert_not_reached ();  return G_TYPE_NONE;}static gbooleanvivi_movie_list_get_iter (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreePath *path){  ViviMovieList *movies = VIVI_MOVIE_LIST (tree_model);  GNode *node;  guint i, depth;  int *indices;  REPORT;  depth = gtk_tree_path_get_depth (path);  indices = gtk_tree_path_get_indices (path);  if (indices == NULL)    return FALSE;  node = movies->root;  for (i = 0; i < depth; i++) {    node = g_node_nth_child (node, indices[i]);    if (node == NULL)      return FALSE;  }  iter->user_data = node;  iter->stamp = movies->stamp;  return TRUE;}static GtkTreePath *vivi_movie_list_node_to_path (GNode *node){  GtkTreePath *path;  path = gtk_tree_path_new ();  while (node->parent != NULL) {    gtk_tree_path_prepend_index (path, g_node_child_position (node->parent, node));    node = node->parent;  }  return path;}static GtkTreePath *vivi_movie_list_get_path (GtkTreeModel *tree_model, GtkTreeIter *iter){  REPORT;  return vivi_movie_list_node_to_path (iter->user_data);}static void vivi_movie_list_get_value (GtkTreeModel *tree_model, GtkTreeIter *iter,    gint column, GValue *value){  SwfdecMovie *movie = ((GNode *) iter->user_data)->data;  REPORT;  switch (column) {    case VIVI_MOVIE_LIST_COLUMN_MOVIE:      g_value_init (value, G_TYPE_POINTER);      g_value_set_pointer (value, movie);      return;    case VIVI_MOVIE_LIST_COLUMN_NAME:      g_value_init (value, G_TYPE_STRING);      if (movie->name[0])	g_value_set_string (value, movie->name);      else	g_value_set_string (value, movie->original_name);      return;    case VIVI_MOVIE_LIST_COLUMN_DEPTH:      g_value_init (value, G_TYPE_INT);      g_value_set_int (value, movie->depth);      return;    case VIVI_MOVIE_LIST_COLUMN_TYPE:      g_value_init (value, G_TYPE_STRING);      /* big hack: we skip the "Swfdec" here */      g_value_set_string (value, G_OBJECT_TYPE_NAME (movie) + 6);      return;    default:      break;  }  g_assert_not_reached ();}static gbooleanvivi_movie_list_iter_next (GtkTreeModel *tree_model, GtkTreeIter *iter){  GNode *node;  REPORT;  node = iter->user_data;  node = node->next;  if (node == NULL)    return FALSE;  iter->user_data = node;  return TRUE;}static gbooleanvivi_movie_list_iter_children (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent){  GNode *node;  REPORT;  if (parent) {    node = parent->user_data;  } else {    node = VIVI_MOVIE_LIST (tree_model)->root;  }  if (node->children == NULL)    return FALSE;  iter->user_data = node->children;  return TRUE;}static gbooleanvivi_movie_list_iter_has_child (GtkTreeModel *tree_model, GtkTreeIter *iter){  GtkTreeIter unused;  REPORT;  return vivi_movie_list_iter_children (tree_model, &unused, iter);}static gintvivi_movie_list_iter_n_children (GtkTreeModel *tree_model, GtkTreeIter *iter){  GNode *node;  REPORT;  if (iter) {    node = iter->user_data;  } else {    node = VIVI_MOVIE_LIST (tree_model)->root;  }  return g_node_n_children (node);}static gbooleanvivi_movie_list_iter_nth_child (GtkTreeModel *tree_model, GtkTreeIter *iter,    GtkTreeIter *parent, gint n){  GNode *node;  REPORT;  if (parent) {    node = parent->user_data;  } else {    node = VIVI_MOVIE_LIST (tree_model)->root;  }  node = g_node_nth_child (node, n);  if (node == NULL)    return FALSE;  iter->user_data = node;  return TRUE;}static gbooleanvivi_movie_list_iter_parent (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *child){  GNode *node;  REPORT;  node = child->user_data;  node = node->parent;  if (node->parent == NULL)    return FALSE;  iter->user_data = node;  return TRUE;}static voidvivi_movie_list_tree_model_init (GtkTreeModelIface *iface){  iface->get_flags = vivi_movie_list_get_flags;  iface->get_n_columns = vivi_movie_list_get_n_columns;  iface->get_column_type = vivi_movie_list_get_column_type;  iface->get_iter = vivi_movie_list_get_iter;  iface->get_path = vivi_movie_list_get_path;  iface->get_value = vivi_movie_list_get_value;  iface->iter_next = vivi_movie_list_iter_next;  iface->iter_children = vivi_movie_list_iter_children;  iface->iter_has_child = vivi_movie_list_iter_has_child;  iface->iter_n_children = vivi_movie_list_iter_n_children;  iface->iter_nth_child = vivi_movie_list_iter_nth_child;  iface->iter_parent = vivi_movie_list_iter_parent;}/*** VIVI_MOVIE_LIST ***/G_DEFINE_TYPE_WITH_CODE (ViviMovieList, vivi_movie_list, G_TYPE_OBJECT,    G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL, vivi_movie_list_tree_model_init))static intvivi_movie_list_get_index (GNode *parent, GNode *new){  GNode *walk;  int i = 0;  for (walk = parent->children; walk; walk = walk->next) {    if (walk == new)      continue;    if (swfdec_movie_compare_depths (walk->data, new->data) < 0) {      i++;      continue;    }    break;  }  return i;}static voidvivi_movie_list_movie_notify (SwfdecMovie *movie, GParamSpec *pspec, ViviMovieList *movies){  GtkTreeIter iter;  GtkTreePath *path;  GNode *node;  node = g_hash_table_lookup (movies->nodes, movie);  if (g_str_equal (pspec->name, "depth")) {    guint old, new;    GNode *parent;    parent = node->parent;    old = g_node_child_position (parent, node);    new = vivi_movie_list_get_index (parent, node);    if (old != new) {      /* reorder */      guint min = MIN (old, new);      guint max = MAX (old, new);      guint i;      guint count = g_node_n_children (parent);      int *positions = g_new (int, count);      for (i = 0; i < min; i++) {	positions[i] = i;      }      if (old < new) {	for (i = min; i < max; i++) {	  positions[i] = i + 1;	}      } else {	for (i = min + 1; i <= max; i++) {	  positions[i] = i - 1;	}      }      positions[new] = old;      for (i = max + 1; i < count; i++) {	positions[i] = i;      }      g_node_unlink (node);      g_node_insert (parent, new, node);      iter.stamp = movies->stamp;      iter.user_data = parent;      path = vivi_movie_list_node_to_path (parent);      gtk_tree_model_rows_reordered (GTK_TREE_MODEL (movies), path, &iter, positions);      gtk_tree_path_free (path);      g_free (positions);    }  }  iter.stamp = movies->stamp;  iter.user_data = node;  path = vivi_movie_list_node_to_path (node);  gtk_tree_model_row_changed (GTK_TREE_MODEL (movies), path, &iter);  gtk_tree_path_free (path);}static gbooleanvivi_movie_list_added (ViviDebugger *debugger, SwfdecAsObject *object, ViviMovieList *movies){  SwfdecMovie *movie;  GtkTreePath *path;  GtkTreeIter iter;  GNode *node, *new;  int pos;  if (!SWFDEC_IS_MOVIE (object))    return FALSE;  movie = SWFDEC_MOVIE (object);  g_signal_connect (movie, "notify", G_CALLBACK (vivi_movie_list_movie_notify), movies);  if (movie->parent) {    node = g_hash_table_lookup (movies->nodes, movie->parent);    g_assert (node);  } else {    node = movies->root;  }  new = g_node_new (movie);  g_hash_table_insert (movies->nodes, movie, new);  pos = vivi_movie_list_get_index (node, new);  g_node_insert (node, pos, new);  movies->stamp++;  iter.stamp = movies->stamp;  iter.user_data = new;  path = vivi_movie_list_node_to_path (new);  gtk_tree_model_row_inserted (GTK_TREE_MODEL (movies), path, &iter);  gtk_tree_path_free (path);  return FALSE;}static voidvivi_movie_list_remove_node (ViviMovieList *movies, GNode *node){  GNode *walk;  for (walk = node->children; walk; walk = walk->next) {    vivi_movie_list_remove_node (movies, walk);  }  g_hash_table_remove (movies->nodes, node->data);  g_signal_handlers_disconnect_by_func (node->data, vivi_movie_list_movie_notify, movies);}static gbooleanvivi_movie_list_removed (ViviDebugger *debugger, SwfdecAsObject *object, ViviMovieList *movies){  GNode *node;  GtkTreePath *path;  if (!SWFDEC_IS_MOVIE (object))    return FALSE;  node = g_hash_table_lookup (movies->nodes, object);  /* happens when parent was already removed */  if (node == NULL)    return FALSE;  vivi_movie_list_remove_node (movies, node);  path = vivi_movie_list_node_to_path (node);  g_node_destroy (node);  gtk_tree_model_row_deleted (GTK_TREE_MODEL (movies), path);  gtk_tree_path_free (path);  return FALSE;}static voidvivi_movie_list_reset (ViviApplication *app, GParamSpec *pspec, ViviMovieList *movies){  GNode *walk;  for (walk = movies->root->children; walk; walk = walk->next) {    vivi_movie_list_removed (NULL, walk->data, movies);  }}static voidvivi_movie_list_dispose (GObject *object){  ViviMovieList *movies = VIVI_MOVIE_LIST (object);  ViviDebugger *debugger;  GNode *walk;  debugger = movies->app->debugger;  g_signal_handlers_disconnect_by_func (movies->app, vivi_movie_list_reset, movies);  g_signal_handlers_disconnect_by_func (debugger, vivi_movie_list_removed, movies);  g_signal_handlers_disconnect_by_func (debugger, vivi_movie_list_added, movies);  g_object_unref (movies->app);  for (walk = movies->root->children; walk; walk = walk->next) {    vivi_movie_list_remove_node (movies, walk);  }  g_node_destroy (movies->root);#ifndef G_DISABLE_ASSERT  if (g_hash_table_size (movies->nodes) != 0) {    g_error ("%u items left in hash table", g_hash_table_size (movies->nodes));  }#endif  g_hash_table_destroy (movies->nodes);  G_OBJECT_CLASS (vivi_movie_list_parent_class)->dispose (object);}static voidvivi_movie_list_class_init (ViviMovieListClass *class){  GObjectClass *object_class = G_OBJECT_CLASS (class);  object_class->dispose = vivi_movie_list_dispose;}static voidvivi_movie_list_init (ViviMovieList *movies){  movies->root = g_node_new (NULL);  movies->nodes = g_hash_table_new (g_direct_hash, g_direct_equal);}GtkTreeModel *vivi_movie_list_new (ViviApplication *app){  ViviMovieList *movies;  ViviDebugger *debugger;  movies = g_object_new (VIVI_TYPE_MOVIE_LIST, NULL);  g_object_ref (app);  movies->app = app;  debugger = app->debugger;  g_signal_connect (app, "notify::player", G_CALLBACK (vivi_movie_list_reset), movies);  g_signal_connect (debugger, "add", G_CALLBACK (vivi_movie_list_added), movies);  g_signal_connect (debugger, "remove", G_CALLBACK (vivi_movie_list_removed), movies);  return GTK_TREE_MODEL (movies);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -