首页 > 其他分享 >Clutter学习(十四):用一个较大的例子来复习

Clutter学习(十四):用一个较大的例子来复习

时间:2023-05-08 18:33:04浏览次数:50  
标签:angle 复习 timeline actor behaviour item Clutter clutter 十四


我们已经学习了clutter的基本用法,用一个较大的例子来进行复习,例子来源:http://www.openismus.com/documents/clutter_tutorial/0.9/docs/tutorial/html/sec-full-example.html 。这个教程是基于clutter0.9的,在clutter1.0上需要做小小的改动。下面是clutter1.0上的这个例子的重写:

#include <clutter/clutter.h>
 #include <stdlib.h>

 const gint ELLIPSE_Y = 390;
 const gint ELLIPSE_HEIGHT = 450;
 const gint IMAGE_HEIGHT = 100;
 double angle_step = 30;

 ClutterTimeline  * timeline_rotation = NULL, * timeline_moveup = NULL;
 ClutterActor     * label_filename = NULL;
 ClutterBehaviour * behaviour_scale = NULL , * behaviour_path = NULL,
                  * behaviour_opacity = NULL;

 typedef struct Item{
         ClutterActor            * actor;
         ClutterBehaviour        * ellipse_behaviour;
         gchar                   * filepath;
 }Item;
 Item* item_at_front = NULL;
 GSList *list_items = 0;

 void rotate_all_until_item_is_at_front(Item * item);

 gdouble angle_in_360(gdouble angle){
         gdouble result = angle;
         while(result >= 360)
                  result -= 360;
   
         return result;
 }

 void on_foreach_clear_list_items(gpointer data, gpointer user_data)
 {
         if(data == NULL)
                 return;
         Item* item = (Item*)data;

         /* We don't need to unref the actor because the floating reference was taken by the stage. */ 
         g_object_unref (item->ellipse_behaviour);
         g_free (item->filepath);
         g_free (item);
 }

 void scale_texture_default(ClutterActor * texture){
         int pixbuf_height = 0;
         clutter_texture_get_base_size (CLUTTER_TEXTURE (texture), NULL, 
          &pixbuf_height);
         const gdouble scale = pixbuf_height ?   IMAGE_HEIGHT /  (gdouble)pixbuf_height : 0;
         clutter_actor_set_scale (texture, scale, scale);

 }

 void load_images(const gchar* directory_path){
         g_return_if_fail(directory_path);
         /* Clear any existing images: */ 
         g_slist_foreach (list_items, on_foreach_clear_list_items, NULL);
         g_slist_free (list_items);

         /* Create a new list: */ 
         list_items = NULL;

         GError * error = NULL;
         GDir * dir = g_dir_open(directory_path,0,&error);
         if(error) {
                 g_warning("g_dir_open() failed: %s/n", error->message);
                 g_clear_error(&error);
                 return;
         }

         int i = 0;
         const gchar * filename = NULL;
         while ( (filename = g_dir_read_name(dir)) != NULL){
                 gchar* path = g_build_filename (directory_path, filename, NULL);
                 printf("%2d  %s/n",++i, path);
                 ClutterActor * actor = clutter_texture_new_from_file(path,NULL);
                 if(actor){
                         Item * item = g_new0(Item,1);
                         item -> actor = actor;
                         item -> filepath = g_strdup (path);
                         scale_texture_default(item->actor);
                         list_items = g_slist_append(list_items,item);
                 }
                 g_free(path);
         }
         angle_step = 360.0/i;
         printf("total %d image, angel step is %.1f/n",i,angle_step);
 }

 gboolean on_texture_button_press(ClutterActor * actor ,ClutterEvent * event,
  gpointer user_data){
         if(timeline_rotation && clutter_timeline_is_playing(timeline_rotation)){
                 printf("on_texture_button_press() : ignoring/n");
                 return FALSE;
         }else{
                 printf("on_texture_button_press() : handling/n");
         }
         Item * item = (Item *) user_data;
         rotate_all_until_item_is_at_front(item);
         return TRUE;
 }

 void add_to_ellipse_behaviour(ClutterTimeline *timeline_rotation,  gdouble start_angle, Item *item){
         g_return_if_fail (timeline_rotation);
         ClutterAlpha *alpha = clutter_alpha_new_full (timeline_rotation, 
          CLUTTER_EASE_OUT_SINE);
         /*if start is equal to end, the behaviour will rotate by exacly 360 degrees.*/ 
         item->ellipse_behaviour = clutter_behaviour_ellipse_new (alpha, 320, ELLIPSE_Y, /* x, y */ 
          ELLIPSE_HEIGHT, ELLIPSE_HEIGHT/* width, height */ , CLUTTER_ROTATE_CW,
          start_angle, start_angle );
         clutter_behaviour_ellipse_set_angle_tilt ( CLUTTER_BEHAVIOUR_ELLIPSE (item->ellipse_behaviour), 
          CLUTTER_X_AXIS, -90.0);
         clutter_behaviour_apply (item->ellipse_behaviour, item->actor);
 }


 void add_image_actors(ClutterActor * stage){
         int x = 20;
         int y = 0;
         gdouble angle = 0;
         GSList * list = list_items;
         while(list){
                 Item * item = (Item *) list->data;
                 ClutterActor * actor = item->actor;
                 clutter_actor_set_position(actor,x,y);
                 y += 100;
                 clutter_container_add_actor(CLUTTER_CONTAINER(stage),actor);

                 /* Allow the actor to emit events. By default only the stage does this.  */ 
                 clutter_actor_set_reactive (actor, TRUE);
                 g_signal_connect (actor, "button-press-event",
                  G_CALLBACK (on_texture_button_press), item);
                 while(angle >= 360)
                         angle -= 360;
                 add_to_ellipse_behaviour(timeline_rotation,angle,item);
                 angle += angle_step;


                 list = g_slist_next(list);
         }
 }

 void on_timeline_moveup_completed(ClutterTimeline* timeline, gpointer user_data)
 {
         /* Unref this timeline because we have now finished with it: */ 
         g_object_unref (timeline_moveup);
         timeline_moveup = NULL;

         g_object_unref (behaviour_scale);
         behaviour_scale = NULL;

         g_object_unref (behaviour_path);
         behaviour_path = NULL;

         g_object_unref (behaviour_opacity);
         behaviour_opacity = NULL;
 }


 void on_timeline_rotation_completed(ClutterTimeline * timeline,  gpointer user_data){
         ClutterActor * actor = item_at_front->actor;
         timeline_moveup = clutter_timeline_new(1200 /* milliseconds */);

         /*for Scaling*/ 
         ClutterAlpha *alpha = clutter_alpha_new_full (timeline_moveup, CLUTTER_EASE_OUT_SINE);
         gdouble scale_start = 0;
         clutter_actor_get_scale (actor, &scale_start, NULL);
         const gdouble scale_end = scale_start * 1.80;
         behaviour_scale = clutter_behaviour_scale_new (alpha, scale_start, scale_start, scale_end, scale_end);
         clutter_behaviour_apply (behaviour_scale, actor);

         /* Move the item up the y axis: */ 
   
         ClutterKnot knots[2];
         knots[0].x = clutter_actor_get_x (actor);
         knots[0].y = clutter_actor_get_y (actor);
         knots[1].x = knots[0].x - 80;
         knots[1].y = knots[0].y - 255;

         printf("move from (%d,%d) to (%d, %d)/n",knots[0].x,knots[0].y,knots[1].x,knots[1].y);
         behaviour_path = clutter_behaviour_path_new_with_knots (alpha, knots, G_N_ELEMENTS(knots));
         clutter_behaviour_apply (behaviour_path, actor);

         /*Show the file name */ 
         clutter_text_set_text (CLUTTER_TEXT (label_filename), item_at_front->filepath);
         behaviour_opacity = clutter_behaviour_opacity_new (alpha, 0, 255);
         clutter_behaviour_apply (behaviour_opacity, label_filename);

         /*After it complete unref the param */ 
         g_signal_connect (timeline_moveup, "completed", G_CALLBACK (on_timeline_moveup_completed), NULL);

         clutter_timeline_start (timeline_moveup);

 }

 void rotate_all_until_item_is_at_front(Item * item){
         g_return_if_fail (item);
         clutter_timeline_stop(timeline_rotation);
         if(timeline_moveup != NULL)
                 clutter_timeline_stop(timeline_moveup);
         clutter_actor_set_opacity (label_filename, 0);
        /* Get the item's position in the list: */ 
         const gint pos = g_slist_index (list_items, item);
         printf("We want to show pos = %d/n",pos);
         g_assert (pos != -1);
         if(!item_at_front && list_items)
                 item_at_front = (Item*)list_items->data;

         gint pos_front = 0;
         if(item_at_front)
                 pos_front = g_slist_index (list_items, item_at_front);
         printf("Current front pos is %d/n",pos_front);
         g_assert (pos_front != -1);
        /* Calculate the end angle of the first item: */ 
         const gdouble angle_front = 90;
         gdouble angle_start = angle_front - (angle_step * pos_front);
         angle_start= angle_in_360(angle_start);
         gdouble angle_end = angle_front - (angle_step * pos);
         printf("angle (%.0f %.0f)/n",angle_start,angle_end);

         gdouble angle_diff = 0;

         GSList *list = list_items;
         gint i = 0;
         while(list){
                 Item * this_item = (Item*)list->data;
                /* Reset its size: */ 
                 scale_texture_default (this_item->actor);
                 angle_start = angle_in_360 (angle_start);
                 angle_end = angle_in_360 (angle_end);
                 if(item_at_front == item)
                         angle_end += 360;
                 angle_end = angle_in_360 (angle_end);
                 clutter_behaviour_ellipse_set_angle_start (
                  CLUTTER_BEHAVIOUR_ELLIPSE (this_item->ellipse_behaviour), angle_start);
                 clutter_behaviour_ellipse_set_angle_end (
                  CLUTTER_BEHAVIOUR_ELLIPSE (this_item->ellipse_behaviour), angle_end);
                 if(this_item == item){
                         if(angle_start < angle_end)
                                 angle_diff =  angle_end - angle_start;
                         else
                                 angle_diff = 360 - (angle_start - angle_end);
                         printf("  debug: angle diff=%f/n", angle_diff); 
                 }

                // printf("%2d angle %.0f,%.0f/n", ++i,angle_start,angle_end); 
                 angle_end += angle_step;
                 angle_start += angle_step;
                 list = g_slist_next(list);
         }

         const gint count = g_slist_length(list_items);
         gint pos_to_move = count + pos_front - pos;
         if(pos_to_move > count)
                 pos_to_move -= count;
         int duration = (int) (5000.0/count * pos_to_move);
         printf("old is %d want %d pos to move = %d duration = %d/n", pos_front,pos,pos_to_move,duration);

         clutter_timeline_set_duration (timeline_rotation, duration);
         item_at_front = item;
         clutter_timeline_start (timeline_rotation);
 }

 int main(int argc, char * argv[]){
         clutter_init(&argc,&argv);

         ClutterColor stage_color = {0xB0,0xB0,0xB0,0xff};
         ClutterActor * stage = clutter_stage_get_default();
         clutter_actor_set_size(stage,800,600);
         clutter_stage_set_color(CLUTTER_STAGE(stage),&stage_color);

         /* Create and add a label actor, hidden at first: */ 
         label_filename = clutter_text_new();
         ClutterColor label_color = {0x00,0x00,0x00,0xff};
         clutter_text_set_color( CLUTTER_TEXT(label_filename),&label_color);
         clutter_text_set_font_name (CLUTTER_TEXT (label_filename), "微软雅黑 18");
         clutter_actor_set_position (label_filename, 10, 10);
         clutter_actor_set_opacity (label_filename, 0);
         clutter_container_add_actor (CLUTTER_CONTAINER (stage), label_filename);

        /* Add a plane under the ellipse of images: */ 
         ClutterColor rect_color = { 0xff, 0xff, 0xdf, 0xff }; /* white */
         ClutterActor *rect = clutter_rectangle_new_with_color (&rect_color);
         clutter_actor_set_height (rect, ELLIPSE_HEIGHT + 20);
         clutter_actor_set_width (rect, clutter_actor_get_width (stage) + 100);
         clutter_actor_set_position (rect, -(clutter_actor_get_width(rect) - clutter_actor_get_width(stage)) / 2, 
          ELLIPSE_Y + IMAGE_HEIGHT - (clutter_actor_get_height (rect) / 2));
         clutter_actor_set_rotation (rect, CLUTTER_X_AXIS, 90.0, 0.0, (clutter_actor_get_height (rect) / 2.0), 0.0);
         clutter_container_add_actor (CLUTTER_CONTAINER (stage), rect);

         timeline_rotation = clutter_timeline_new(5000);
         g_signal_connect (timeline_rotation, "completed", G_CALLBACK (on_timeline_rotation_completed), NULL);

         /* Add an actor for each image: */ 
         load_images("./images/");
         add_image_actors(stage);
         if(list_items)
                 rotate_all_until_item_is_at_front ((Item*)list_items->data);

         clutter_actor_show_all(stage);
         clutter_main();

         g_object_unref (timeline_rotation);
         return EXIT_SUCCESS;
 }


Clutter学习(十四):用一个较大的例子来复习_path


标签:angle,复习,timeline,actor,behaviour,item,Clutter,clutter,十四
From: https://blog.51cto.com/u_9877302/6255397

相关文章

  • python快速直白入门(半新手向,老手复习向)
    主用python做项目有一段时间,这次简单总结学习下。为后面的项目编写,进行一次基础知识的查缺补漏、1、变量名和数据类型"""变量名,只能由"数字、大小写字母、_"组成,且不能以数字开头"""#整数int#hashable,不可变对象a=5#浮点数float#hashable,不可变对象a1=3......
  • 十四、JVM-垃圾相关算法(基础篇)
    一、标记阶段:引用计数算法1、对象存活判断在堆里存放着几乎所有的Java对象实例,在GC执行垃圾回收之前,首先需要区分出内存中哪些是存活对象,哪些是已经死亡的对象。只有被标记为己经死亡的对象,GC才会在执行垃圾回收时,释放掉其所占用的内存空间,因此这个过程我们可以称为垃圾标记阶......
  • Spring复习笔记
    Spring架构核心概念IOC&DIIOCDIbeanbean的实例化......
  • abp(net core)+easyui+efcore实现仓储管理系统——供应商管理升级之下(六十四)
    abp(netcore)+easyui+efcore实现仓储管理系统目录abp(netcore)+easyui+efcore实现仓储管理系统——ABP总体介绍(一)abp(netcore)+easyui+efcore实现仓储管理系统——解决方案介绍(二)abp(netcore)+easyui+efcore实现仓储管理系统——领域层创建实体(三) abp(netcore)+eas......
  • (网工复习 考完删)第四章 计算机网络基础
    1.网络应用的用户类型和目标1.1商业公司内部共享物理与信息资源,打破地理位置的束缚通信媒介电子商务1.2个人与家庭服务访问远程信息个人通信娱乐电子商务1.3移动用户移动办公军事网络城市管理自动售货机位置服务增强现实2.网络的发展阶段第一阶段:面向终......
  • (网工复习 考完删)第二章 网络与图
    1.七桥问题找到一个路径包含每一条边且边不重复证明该图不存在符合条件的路径:每一个度数为奇数的节点只能是路径的起点或终点图中有四个度数为奇数的节点一条路径只能有一个起点和终点2.图的联通性联通:每一对顶点之间都存在路径不联通:包含多个联通片联通片:联通的孤立......
  • (网工复习 考完删)第三章 网络基本拓扑性质
    1.无向网络中的巨片概念许多实际的大规模复杂网络都是不联通的,但是往往会存在一个特别大的联通片,他包含了整个节点中相当比例的节点,这一联通片成为巨片(Giantcomponent)无向网络的联通巨片的存在唯一性2.巨片的蝴蝶结结构(Bow-tiestructure)强联通核(Strongconnectedcore,......
  • Go笔记(十四):通道 channel
    1、通道通道channel是Go提供的一种用于各个协程(goroutine)之间的数据共享,保证数据同步交换的机制。协程是轻量级线程,类似于Java中的线程。2、通道的类型2.1、无缓冲通道用于同步通信,可保证在发送和接收数据时完成两个goroutine(协程)的数据交换。2.2、缓冲通道......
  • 分布式系统复习
    这啥玩意都没讲的课要考了。。。1.云计算与大数据1.1云计算的3个服务模型IaaS,基础设施即服务PaaS,平台即服务SaaS,软件即服务云计算的3中服务模型之间的关系:IaaS提供虚拟化的硬件资源,支撑PaaS对平台的虚拟化,而PaaS又支撑了SaaS对软件的虚拟化。1.2DIKW体系Data(数据)、Info......
  • 第十四天第一个问题
    问题描述:以点类Point为基类公有派生圆类Circle,main(void)函数完成对其的测试。Point类结构说明:Point类的数据成员包括:①私有数据成员:X坐标x(double型),Y坐标y(double型)。Point类成员函数包括:①有参构造函数Point(double,double)和拷贝构造函数Point(constPoint&),其中有......