Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1724806
  • 博文数量: 362
  • 博客积分: 10587
  • 博客等级: 上将
  • 技术积分: 4098
  • 用 户 组: 普通用户
  • 注册时间: 2009-09-10 18:15
文章分类

全部博文(362)

文章存档

2014年(1)

2013年(58)

2011年(115)

2010年(112)

2009年(76)

分类: C/C++

2010-02-21 15:56:59

#include
#include
#include
#include
#include
enum            /*定义图形的类型*/
{
    PIX_DRAW=1,    /*类型-点*/
    LINE_DRAW,
    CIRCLE_DRAW,
    RECT_DRAW,
    POLY_DRAW
};
typedef struct        /*定义含树视图和绘图区的结构体,以便回调函数传递参数*/
{
    GtkWidget *tree_view;
    GtkWidget *draw_area;
}tree_drawing;
typedef struct        /*定义含树视图、绘图区和文本输入框的结构体,以便回调函数传递参数*/
{
    GtkWidget *window;
    GtkWidget *view;
    GtkWidget *entry;
}wview;
typedef struct        /*为方便参数传递而创建的结构体*/
{
    GtkWidget *window;
    GtkWidget *view;
    GtkWidget *entry;
    GtkWidget *draw_area;
}wdview;
typedef struct _2D_POINT    /*定义二维数据点结构体*/
{
    float x,y;
}_2d_point;
/*------------定义全局变量--------------*/
double width=100.0,height=100.0;    /*定义系统长宽,这里与窗口窗宽无关*/
int draw_type=0;            /*定义图像类型*/
GSList *prt=NULL;            /*定义存放数据的链表*/
GtkTreeModel *model;            /*定义树视图模型*/
GtkTreeStore *tree_store;        /*定义树形存储*/
GtkTreeIter top_pix,top_line,top_circle,top_rect,top_poly,other;    /*定义树视图的项,以便添加元素*/
/*-----------函数声明部分------------------*/
GtkTreeView* create_tree(void);        /*创建树视图*/
GtkTreeModel* create_model(void);    /*创建树视图模型*/
void get_new_file(GtkWidget *button,wview *wv);/*获得文件名,并修改树视图显示*/
void create_file(GtkWidget *create_file_button,GtkWidget *view);/*创建文件菜单的回调函数*/
void get_import_file(GtkWidget* button,wdview *wdv);        /*获得导入文件名,并修改树视图和绘图区显示*/
void messagebox(const char *str);                /*消息提示框,用于提示相关信息*/
void import_file(GtkWidget *import_file_button,tree_drawing *td);/*导入文件菜单的回调函数*/
void export_file(GtkWidget *export_file_button,GtkWidget *view);/*导出文件菜单的回调函数*/
void enlarge_obj(GtkWidget *enlarge,GtkWidget *data);/*工具栏中放大按钮的回调函数,修改绘图区显示*/
void deflate_obj(GtkWidget *deflate,GtkWidget *data);/*工具栏中缩小按钮的回调函数,修改绘图区显示*/
void draw_pix(void);                    /*draw菜单下,points菜单的回调函数*/
void draw_line(void);                    /*Line菜单的回调函数*/
void draw_circle(void);                    /*Circle菜单的回调函数*/
void draw_rect(void);                    /*Rectagle菜单的回调函数*/
void draw_poly(void);                    /*Plygon菜单的回调函数*/
void draw_prt(GtkWidget *data);                /*在绘图区中按照图像类型,将链表内容绘制出来,修改绘图区显示*/
/*下面这几个函数都没实现,这里不做具体介绍*/
/*
void show_part(GtkWidget *view,GtkWidget *draw_area);
void hide_part(GtkWidget *view,GtkWidget *draw_are);
void del_part(GtkWidget *view,GtkWidget *draw_area);
void modify_part(GtkWidget *view,GtkWidget *draw_area);
GtkWidget* pop_menu(GtkWidget *draw_area);
static gboolean view_press(GtkWidget *widget,GdkEventButton *event,GtkWidget *menu);
*/
/*-----------函数定义部分------------*/
/*
GtkWidget* pop_menu(GtkWidget *draw_area)
{
    GtkWidget *file_menu;
    GtkWidget *show_item,*hide_item,*del_item,*modify_item;
    show_item=gtk_menu_item_new_with_label("show");
    hide_item=gtk_menu_item_new_with_label("hide");
    del_item=gtk_menu_item_new_with_label("delete");
    modify_item=gtk_menu_item_new_with_label("modify");
    gtk_menu_append(GTK_MENU(file_menu),show_item);
    gtk_menu_append(GTK_MENU(file_menu),hide_item);
    gtk_menu_append(GTK_MENU(file_menu),del_item);
    gtk_menu_append(GTK_MENU(file_menu),modify_item);
    g_signal_connect_swapped(G_OBJECT(show_item),"activate",G_CALLBACK(show_part),draw_area);
    g_signal_connect_swapped(G_OBJECT(hide_item),"activate",G_CALLBACK(hide_part),draw_area);
    g_signal_connect_swapped(G_OBJECT(del_item),"activate",G_CALLBACK(del_part),draw_area);
    g_signal_connect_swapped(G_OBJECT(modify_item),"activate",G_CALLBACK(modify_part),draw_area);
    return file_menu;
}
void show_part(GtkWidget *view,GtkWidget *draw_area)
{
}
void hide_part(GtkWidget *view,GtkWidget *draw_are)
{
}
void del_part(GtkWidget *view,GtkWidget *draw_area)
{
}
void modify_part(GtkWidget *view,GtkWidget *draw_area)
{
}
*/
/*上面几个函数都还没实现,由于事件问题,在这里就不具体实现了*/
/*-----------函数定义部分-------------*/
/*创建树视图,向里面添加列,并调用树视图模型创建函数完成树视图的创建,
 * 输入参数:无
 * 输出参数:树视图构件tree_view
 * 日期:2007-4-7修改*/
GtkTreeView* create_tree(void)
{
    GtkWidget *tree_view;
    GtkTreeViewColumn *col;
    GtkCellRenderer *cell;
   
    tree_view=gtk_tree_view_new();
    col=gtk_tree_view_column_new();
    gtk_tree_view_column_set_title(col,"part");
    gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view),col);
    cell=gtk_cell_renderer_text_new();
        //g_object_set(cell,"editable",TRUE,NULL);
    //g_signal_connect(cell,"edited",G_CALLBACK(cell_edited),NULL);
    gtk_tree_view_column_pack_start(col,cell,TRUE);
    gtk_tree_view_column_add_attribute(col,cell,"text",0);
    model=create_model();
    gtk_tree_view_set_model(GTK_TREE_VIEW(tree_view),model);
    return GTK_TREE_VIEW(tree_view);
}
/*创建树视图模型,向tree_store里面添加条目
 * 输入参数:无
 * 输出参数:树视图模型tree_store
 * 日期:2007-4-7修改*/
GtkTreeModel* create_model()
{
    tree_store=gtk_tree_store_new(1,G_TYPE_STRING);
    //添加树的项
    gtk_tree_store_append(tree_store,&top_pix,NULL);
    gtk_tree_store_set(tree_store,&top_pix,
        0,"Points",-1);
    gtk_tree_store_append(tree_store,&top_line,NULL);
    gtk_tree_store_set(tree_store,&top_line,
        0,"Lines",-1);
    gtk_tree_store_append(tree_store,&top_circle,NULL);
    gtk_tree_store_set(tree_store,&top_circle,
        0,"Circles",-1);
    gtk_tree_store_append(tree_store,&top_rect,NULL);
    gtk_tree_store_set(tree_store,&top_rect,
        0,"Rectangles",-1);
    gtk_tree_store_append(tree_store,&top_poly,NULL);
    gtk_tree_store_set(tree_store,&top_poly,
        0,"Polygons",-1);
    gtk_tree_store_append(tree_store,&other,NULL);
    gtk_tree_store_set(tree_store,&other,
        0,"Others",-1);
    return GTK_TREE_MODEL(tree_store);
}
/*获得文本输入框内容,并将其加入到树视图中显示,并隐藏新建文件窗口
 * 输入参数:按钮构件本身button,包含文本输入框、树视图和绘图区的结构体wv
 * 输出参数:无
 * 日期:2007-4-7修改*/
void get_new_file(GtkWidget *button,wview *wv)
{
    char *str=malloc(20*sizeof(char));
    str=(char*)gtk_entry_get_text(GTK_ENTRY(wv->entry));
    GtkTreeIter child;
    gtk_tree_store_append(tree_store,&child,&other);/*向树存储类型的构件中添加条目*/
    gtk_tree_store_set(tree_store,&child,        /*设置新添加条目的文本显示*/
        0,str,-1);
    /*FILE *fp=NULL;
    if((fp=fopen(str,"w"))==NULL)
        printf("error in open file %s\n",str);
    fclose(fp);*/
    gtk_widget_hide(wv->window);
}
/*隐藏窗口,
 * 输入参数:按钮button,窗口构件window
 * 输出参数:无
 * 日期:2007-4-7修改*/
void cancel_create(GtkWidget *button,GtkWidget *window)
{
    gtk_widget_hide(window);
}
/*创建文件菜单的回调函数。用于打开一个对话框,让用户输入文件名,然后将文件名放到树视图的other条目下,创建文件,
 * 输入参数:菜单项本身create_file_item, 树视图view
 * 输出参数:无
 * 日期:2007-4-7修改*/
void create_file(GtkWidget *create_file_button,GtkWidget *view)
{
    GtkWidget *window,*entry;
    GtkWidget *label,*vbox,*hbox,*b_ok,*b_cancel;
   
    window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_widget_set_size_request(window,300,110);
    gtk_window_set_title(GTK_WINDOW(window),"create part file");
    g_signal_connect(G_OBJECT(window),"destroy",G_CALLBACK(gtk_widget_destroy),NULL);
    gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
   
    vbox=gtk_vbox_new(FALSE,15);
    gtk_container_add(GTK_CONTAINER(window),vbox);
   
    label=gtk_label_new("Please input the file name:");
    gtk_box_pack_start(GTK_BOX(vbox),label,FALSE,FALSE,0);
    entry=gtk_entry_new();
    gtk_box_pack_start(GTK_BOX(vbox),entry,FALSE,FALSE,0);
    hbox=gtk_hbox_new(FALSE,0);
    gtk_box_pack_start(GTK_BOX(vbox),hbox,FALSE,FALSE,0);
    wview *wv=malloc(sizeof(wview));
    wv->window=window;
    wv->view=view;
    wv->entry=entry;
    b_ok=gtk_button_new_with_label("  ok   ");
    g_signal_connect(G_OBJECT(b_ok),"clicked",G_CALLBACK(get_new_file),wv);
    gtk_box_pack_start(GTK_BOX(hbox),b_ok,FALSE,FALSE,50);
    b_cancel=gtk_button_new_with_label("cancel");
    g_signal_connect(G_OBJECT(b_cancel),"clicked",G_CALLBACK(cancel_create),window);
   
    gtk_box_pack_start(GTK_BOX(hbox),b_cancel,FALSE,FALSE,50);
    gtk_widget_show_all(window);
}
/*用于隐藏构件,这里是将messagebox窗口隐藏,
 * 输入参数:按钮本身button,窗口构件data
 * 输出参数:无
 * 日期:2007-4-7修改*/
void f_button(GtkWidget * button,GtkWidget * data)
{
    gtk_widget_hide(data);
}
/*一个消息提示框,弹出一个窗口,用于提示当前的错误或者其它信息
 * 输入参数:字符串str
 * 输出参数:无
 * 日期:2007-4-7修改*/
void messagebox(const char* str)
{
    GtkWidget * window,*table,*label,*button;
    /////
    window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window),"messagebox");
    gtk_widget_set_size_request(GTK_WIDGET(window),300,100);
    gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
    g_signal_connect(G_OBJECT(window),"destroy",G_CALLBACK(gtk_widget_destroy),NULL);
    /////
    table=gtk_table_new(2,3,FALSE);
    gtk_container_add(GTK_CONTAINER(window),table);
    ///
    label=gtk_label_new(str);
    gtk_table_attach_defaults(GTK_TABLE(table),label,1,2,0,1);
    gtk_widget_show(label);
   
   
    button=gtk_button_new_with_label("     确定     ");
    gtk_table_attach(GTK_TABLE(table),button,1,2,1,2,GTK_SHRINK,GTK_FILL,0,0);
    g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(f_button),window);
    gtk_widget_show(button);
    gtk_widget_show_all(window);
}
/*导入文件对话框ok按钮的回调函数,实现读取文件名,并在将文件内容读取到链表结束后,
 * 根据图形类型修改树视图和绘图区,将文件名添加到树视图的相应条目下。
 * 输出参数:按钮本身:button,包含标签、树视图和绘图区的一个结构体
 * 输出参数:无
 * 日期:2007-4-7修改*/
void get_import_file(GtkWidget* button,wdview *wdv)
{
    char *str=malloc(20*sizeof(char));
    str=(char*)gtk_entry_get_text(GTK_ENTRY(wdv->entry));
    char *filename=malloc(20*sizeof(char));
    sprintf(filename,"%s.124",str);
    FILE *fp=NULL;
    if((fp=fopen(filename,"r"))==NULL)
    {
    messagebox("the file you import is not exist !");
    return ;
    }
    char ch;
    _2d_point *p=malloc(sizeof(_2d_point));
    fscanf(fp,"%c",&ch);
    GtkTreeIter child;
    if(ch=='P')            //判断是哪种类型的部件,以便放到对应目录下
    {
    gtk_tree_store_append(tree_store,&child,&top_pix);
    gtk_tree_store_set(tree_store,&child,
        0,str,-1);
    draw_type=PIX_DRAW;
    }
    else if(ch=='L')
    {
    gtk_tree_store_append(tree_store,&child,&top_line);
    gtk_tree_store_set(tree_store,&child,
        0,str,-1);
    draw_type=LINE_DRAW;
    }
    else if(ch=='C')
    {
    gtk_tree_store_append(tree_store,&child,&top_circle);
    gtk_tree_store_set(tree_store,&child,
        0,str,-1);
    draw_type=CIRCLE_DRAW;
    }
    else if(ch=='R')
    {
    gtk_tree_store_append(tree_store,&child,&top_rect);
    gtk_tree_store_set(tree_store,&child,
        0,str,-1);
    draw_type=RECT_DRAW;
    }
    else if(ch=='D')
    {
    gtk_tree_store_append(tree_store,&child,&top_poly);
    gtk_tree_store_set(tree_store,&child,
        0,str,-1);
    draw_type=POLY_DRAW;
    }
    else
    {
        gtk_tree_store_append(tree_store,&child,&other);
        gtk_tree_store_set(tree_store,&child,
        0,str,-1);
    }
    GSList *iter1=prt;
    while(iter1)//删除数组中原来内容
    {
    prt=g_slist_remove_link(prt,iter1);
    g_slist_free(iter1);
    iter1=prt;
    }
    while(!feof(fp))
    {
    p=malloc(sizeof(_2d_point));
    int ret=fscanf(fp,"%f",&(p->x));
    ret=fscanf(fp,"%f",&(p->y));
    if(ret!=1)
    {
        break;
    }
    prt=g_slist_append(prt,p);
    }
    draw_prt(wdv->draw_area);
   
    gtk_widget_destroy(wdv->window);
    fclose(fp);
}
/*导入菜单的回调函数,创建一个窗口用于输入要导入的文件名,ok按钮的回调函数实现读取文件名,
 * 将文件读取到链表,并修改树视图和绘图区的显示,
 * 输入参数:菜单项本生import_file_button, 包含树视图和绘图区的结构体td
 * 输出参数:无,
 * 日期:2007-4-7修改*/
void import_file(GtkWidget *import_file_button,tree_drawing *td)
{
    GtkWidget *window,*entry;
    GtkWidget *label,*vbox,*hbox,*b_ok,*b_cancel;
   
    window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_widget_set_size_request(window,300,110);
    gtk_window_set_title(GTK_WINDOW(window),"create part file");
    g_signal_connect(G_OBJECT(window),"destroy",G_CALLBACK(gtk_widget_destroy),NULL);
    gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
   
    vbox=gtk_vbox_new(FALSE,15);
    gtk_container_add(GTK_CONTAINER(window),vbox);
   
    label=gtk_label_new("Please input the file you want to import:");
    gtk_box_pack_start(GTK_BOX(vbox),label,FALSE,FALSE,0);
    entry=gtk_entry_new();
    gtk_box_pack_start(GTK_BOX(vbox),entry,FALSE,FALSE,0);
    hbox=gtk_hbox_new(FALSE,50);
    gtk_box_pack_start(GTK_BOX(vbox),hbox,FALSE,FALSE,0);
    wdview *wdv=malloc(sizeof(wdview));
    wdv->window=window;
    wdv->view=td->tree_view;
    wdv->entry=entry;
    wdv->draw_area=td->draw_area;
    b_ok=gtk_button_new_with_label("  ok   ");
    g_signal_connect(G_OBJECT(b_ok),"clicked",G_CALLBACK(get_import_file),wdv);
    gtk_box_pack_start(GTK_BOX(hbox),b_ok,FALSE,FALSE,50);
    b_cancel=gtk_button_new_with_label("cancel");
    g_signal_connect(G_OBJECT(b_cancel),"clicked",G_CALLBACK(cancel_create),window);
   
    gtk_box_pack_start(GTK_BOX(hbox),b_cancel,FALSE,FALSE,0);
    gtk_widget_show_all(window);
}
/*导出文件的回调函数,根据当前选中的树视图中的项,将链表中的数据写到文本文件中,
 * 在文本文件中,第一行是图形的类型,后面的是数据,
 * 存储的文件名就是当前选中的那一行的文本。
 * 输入参数:菜单项本身export_file, 树视图view
 * 输出参数:无
 * 日期:2007-4-7修改*/
void export_file(GtkWidget *export_file,GtkWidget *view)
{
    GtkTreeIter iter;
    GtkTreeView *treeview=(GtkTreeView*)view;
    GtkTreeSelection *selection=gtk_tree_view_get_selection(treeview);/*获得树视图的选定行*/
    if(gtk_tree_selection_get_selected(selection,NULL,&iter))/*从选定行获得选定项*/
    {
    gint i;
    GtkTreePath *path;
    path=gtk_tree_model_get_path(model,&iter);        /*由选定项获得路径。这条在这里无用*/
    //i=gtk_tree_path_get_indeces(path)[0];
    // gtk_tree_store_set (tree_store, &iter, column,
        //                  filename, -1);
    //获得文本
    char *text=malloc(sizeof(char));
    gtk_tree_model_get(GTK_TREE_MODEL(tree_store),&iter,0,&text,-1);/*由项获得项的文本*/
    char *file_name=malloc(19*sizeof(char));
    sprintf(file_name,"%s.124",text);
    FILE *fp=NULL;
    if((fp=fopen(file_name,"w"))==NULL)
    {
        messagebox("conn't open file you saved!");
        return ;
    }
    GSList *iterator=prt;
    char type;
    if(draw_type==PIX_DRAW)
    {
        type='P';
    }
    else if(draw_type==LINE_DRAW)
    {
        type='L';
    }
    else if(draw_type==CIRCLE_DRAW)
    {
        type='C';
    }
    else if(draw_type==RECT_DRAW)
    {
        type='R';
    }
    else if(draw_type==POLY_DRAW)
    {
        type='D';
    }
    else
    {
        messagebox("you have not create file!");
        return ;
    }
    fprintf(fp,"%c\n",type);
    while(iterator)
    {
        fprintf(fp,"%f\t%f\n",((_2d_point*)(iterator->data))->x,((_2d_point*)(iterator->data))->y);
        iterator=iterator->next;
    }
    fclose(fp);
    }
    return;
}
/*绘图函数,根据width和height的值将链表中的数据进行变换到当前坐标系下,由draw_type决定绘制什么图形,
 * 输入参数:绘图区data,
 * 输出参数:无
 * 日期:2007-4-7*/
void draw_prt(GtkWidget *data)
{
    int area_w=100,area_h=100;
    area_w=data->allocation.width;            //获得窗口尺寸
    area_h=data->allocation.height;
    gdk_window_clear(data->window);
    GSList *iter1=NULL,*iter2=NULL;
    iter1=prt;
    if(iter1==NULL){
        return ;
    }
    iter2=prt->next;
    if(draw_type==PIX_DRAW)
    {
        int x,y;
        while(iter1)
        {
            x=(((_2d_point*)(iter1->data))->x)*area_w/width+area_w/2;
            y=(((_2d_point*)(iter1->data))->y)*area_h/height+area_h/2;
            gdk_draw_point(GTK_WIDGET(data)->window,GTK_WIDGET(data)->style->
                fg_gc[GTK_WIDGET_STATE (data)],x,y);
            iter1=iter1->next;
        }
    }
    if(draw_type==LINE_DRAW)
    {
        int x0,x1,y0,y1;
        while(iter2)
        {
            x0=(((_2d_point*)(iter1->data))->x)*area_w/width+area_w/2;
            y0=(((_2d_point*)(iter1->data))->y)*area_h/height+area_h/2;
            x1=(((_2d_point*)(iter2->data))->x)*area_w/width+area_w/2;
            y1=(((_2d_point*)(iter2->data))->y)*area_h/height+area_h/2;           
            gdk_draw_line(GTK_WIDGET(data)->window,GTK_WIDGET(data)->
                style->fg_gc[GTK_WIDGET_STATE (data)],x0,y0,x1,y1);
            iter1=iter2;
            iter2=iter1->next;
        }
    }
    if(draw_type==CIRCLE_DRAW)
    {
        int x0,x1,y0,y1;
        int r=0.0;
        while(iter1&&iter2)
        {
            x0=(((_2d_point*)(iter1->data))->x)*area_w/width+area_w/2;
            y0=(((_2d_point*)(iter1->data))->y)*area_h/height+area_h/2;
            x1=(((_2d_point*)(iter2->data))->x)*area_w/width+area_w/2;
            y1=(((_2d_point*)(iter2->data))->y)*area_h/height+area_h/2;           
            r=sqrt((x1-x0)*(x1-x0)+(y1-y0)*(y1-y0));
            gdk_draw_arc(GTK_WIDGET(data)->window,GTK_WIDGET(data)->style->
                    fg_gc[GTK_WIDGET_STATE (data)],FALSE,x0-r,y0-r,2*r,2*r,0,64*360);
            iter1=iter2->next;
            if(iter1)
            {
                iter2=iter1->next;
            }
        }
    }
    if(draw_type==RECT_DRAW)
    {
        int x0,x1,y0,y1;
        while(iter1&&iter2)
        {
            x0=(((_2d_point*)(iter1->data))->x)*area_w/width+area_w/2;
            y0=(((_2d_point*)(iter1->data))->y)*area_h/height+area_h/2;
            x1=(((_2d_point*)(iter2->data))->x)*area_w/width+area_w/2;
            y1=(((_2d_point*)(iter2->data))->y)*area_h/height+area_h/2;   
            int h=abs(y1-y0);
            int w=abs(x1-x0);
            x0=x0            y0=y0            gdk_draw_rectangle(GTK_WIDGET(data)->window,GTK_WIDGET(data)->style->
                    fg_gc[GTK_WIDGET_STATE (data)],FALSE,x0,y0,w,h);
            iter1=iter2->next;
            if(iter1)
            {
                iter2=iter1->next;
            }
        }
    }
    if(draw_type==POLY_DRAW)
    {
        int x0,x1,y0,y1;
        while(iter2)
        {
            x0=(((_2d_point*)(iter1->data))->x)*area_w/width+area_w/2;
            y0=(((_2d_point*)(iter1->data))->y)*area_h/height+area_h/2;
            x1=(((_2d_point*)(iter2->data))->x)*area_w/width+area_w/2;
            y1=(((_2d_point*)(iter2->data))->y)*area_h/height+area_h/2;               
            gdk_draw_line(GTK_WIDGET(data)->window,GTK_WIDGET(data)->style->
                    fg_gc[GTK_WIDGET_STATE (data)],x0,y0,x1,y1);
            iter1=iter2;
            iter2=iter1->next;
        }
        x0=(((_2d_point*)(iter1->data))->x)*area_w/width+area_w/2;
        y0=(((_2d_point*)(iter1->data))->y)*area_h/height+area_h/2;
        x1=(((_2d_point*)(prt->data))->x)*area_w/width+area_w/2;
        y1=(((_2d_point*)(prt->data))->y)*area_h/height+area_h/2;
        gdk_draw_line(GTK_WIDGET(data)->window,GTK_WIDGET(data)->style->
                fg_gc[GTK_WIDGET_STATE (data)],x0,y0,x1,y1);
    }
}
/*工具栏上放大按钮的回调函数,实现将对象放大显示(通过将全局变量width和height的值改变,并修改绘图区显示),
 * 输入参数:工具栏按钮本身enlarge和绘图区构件data,
 * 输出参数:无,
 * 日期:2007-4-7修改*/
void enlarge_obj(GtkWidget *enlarge,GtkWidget *data)
{
    width=width/1.2;
    height=height/1.2;
    draw_prt(data);
}
/*工具栏上缩小按钮的回调函数,实现将对象缩小显示(通过将全局变量width和height的值改变,并修改绘图区显示),
 * 输入参数:工具栏按钮本身deflate和绘图区构件data,
 * 输出参数:无,
 * 日期:2007-4-7修改*/
void deflate_obj(GtkWidget *deflate,GtkWidget *data)
{
    width=width*1.2;
    height=height*1.2;
    draw_prt(data);
}
/*菜单Draw下的Plygon菜单项的回调函数,实现将全局变量draw_type属性为点,并将存放数据信息的链表清空。
 * 输入参数:无
 * 输出参数:无
 * 时间:2007-4-7修改*/
void draw_pix(void)
{
    //清空绘图区
    //设置图象类型
    GSList *iter1=prt;
    while(iter1)
    {
        prt=g_slist_remove_link(prt,iter1);
        g_slist_free(iter1);
        iter1=prt;
    }
    draw_type=PIX_DRAW;
}
/*菜单Draw下的Plygon菜单项的回调函数,实现将全局变量draw_type属性为线,并将存放数据信息的链表清空。
 * 输入参数:无
 * 输出参数:无
 * 时间:2007-4-7修改*/
void draw_line(void)
{
    // 清空绘图区
    GSList *iter1=prt;
        while(iter1)
    {
        prt=g_slist_remove_link(prt,iter1);
        g_slist_free(iter1);
        iter1=prt;
    }
    draw_type=LINE_DRAW;
}
/*菜单Draw下的Plygon菜单项的回调函数,实现将全局变量draw_type属性为圆,并将存放数据信息的链表清空。
 * 输入参数:无
 * 输出参数:无
 * 时间:2007-4-7修改*/
void draw_circle(void)
{
    //
    GSList *iter1=prt;
    while(iter1)
    {
        prt=g_slist_remove_link(prt,iter1);
        g_slist_free(iter1);
        iter1=prt;
    }
    draw_type=CIRCLE_DRAW;
}
/*菜单Draw下的Plygon菜单项的回调函数,实现将全局变量draw_type属性为矩形,并将存放数据信息的链表清空。
 * 输入参数:无
 * 输出参数:无
 * 时间:2007-4-7修改*/
void draw_rect(void)
{
    //
    GSList *iter1=prt;
    while(iter1)
    {
        prt=g_slist_remove_link(prt,iter1);
        g_slist_free(iter1);
        iter1=prt;
    }
    draw_type=RECT_DRAW;
}
/*菜单Draw下的Plygon菜单项的回调函数,实现将全局变量draw_type属性为多边形,并将存放数据信息的链表清空。
 * 输入参数:无
 * 输出参数:无
 * 时间:2007-4-7修改*/
void draw_poly(void)
{
    //
    GSList *iter1=prt;
    while(iter1)
    {
        prt=g_slist_remove_link(prt,iter1);
        g_slist_free(iter1);
        iter1=prt;
    }
    draw_type=POLY_DRAW;
}
/*创建File菜单
 * 输入参数:包含树视图和绘图区的结构体td,
 * 输出参数:菜单项file_item,
 * 日期:2007-4-7修改*/
GtkWidget* create_file_item(tree_drawing *td)
{
    GtkWidget *file_menu;    //定义菜单
    GtkWidget *file_item;
    GtkWidget *new_file,*import_item,*export_item,*quit_item;    //file 菜单下的菜单项
    char *path=malloc(100*sizeof(char));
    //-------------------创建file菜单----------------------------------
    file_menu=gtk_menu_new();                //创建菜单
        /* 创建菜单项 */
    new_file=gtk_menu_item_new_with_label("New");
        import_item = gtk_menu_item_new_with_label ("Import");
        export_item = gtk_menu_item_new_with_label ("Export");
        quit_item = gtk_menu_item_new_with_label ("Quit");
   
        /* 将它们加到菜单中 */
    gtk_menu_append(GTK_MENU(file_menu),new_file);
        gtk_menu_append (GTK_MENU (file_menu),import_item);
        gtk_menu_append (GTK_MENU (file_menu),export_item);
        gtk_menu_append (GTK_MENU (file_menu),quit_item);   
   
        /* 将回调函数绑定到activate信号 */
    g_signal_connect_swapped(G_OBJECT(new_file),"activate",G_CALLBACK(create_file),td->tree_view);
         g_signal_connect_swapped (G_OBJECT (import_item), "activate",G_CALLBACK (import_file),td);
         g_signal_connect_swapped (G_OBJECT (export_item), "activate", G_CALLBACK (export_file),td->tree_view);   
        g_signal_connect_swapped (G_OBJECT (quit_item), "activate",G_CALLBACK (gtk_main_quit),NULL);
    file_item = gtk_menu_item_new_with_label ("File");
    //gtk_widget_set_size_request(GTK_WIDGET(file_item),50,20);
    gtk_menu_item_set_submenu (GTK_MENU_ITEM (file_item), file_menu);
    return file_item;
}
/*创建菜单Draw
 * 输入参数:无
 * 输出参数:菜单项:draw_menu
 * 日期:2007-4-7修改*/
GtkWidget* create_draw_item(void)
{
    GtkWidget *draw_menu;    //定义菜单
    GtkWidget *draw_item;
    GtkWidget *circle_draw,*rect_draw,*polygon_draw,*line_draw,*pixel_draw;
    draw_menu=gtk_menu_new();
    pixel_draw=gtk_menu_item_new_with_label("Pixel");
    line_draw=gtk_menu_item_new_with_label("Line");
    circle_draw=gtk_menu_item_new_with_label("Circle");
    rect_draw=gtk_menu_item_new_with_label("Rectangle");
    polygon_draw=gtk_menu_item_new_with_label("Polygon");
    gtk_menu_append(GTK_MENU(draw_menu),pixel_draw);
    gtk_menu_append(GTK_MENU(draw_menu),line_draw);
    gtk_menu_append(GTK_MENU(draw_menu),circle_draw);
    gtk_menu_append(GTK_MENU(draw_menu),rect_draw);
    gtk_menu_append(GTK_MENU(draw_menu),polygon_draw);
    g_signal_connect_swapped(G_OBJECT(pixel_draw),"activate",G_CALLBACK(draw_pix),NULL);
    g_signal_connect_swapped(G_OBJECT(line_draw),"activate",G_CALLBACK(draw_line),NULL);
    g_signal_connect_swapped(G_OBJECT(circle_draw),"activate",G_CALLBACK(draw_circle),NULL);
    g_signal_connect_swapped(G_OBJECT(rect_draw),"activate",G_CALLBACK(draw_rect),NULL);
    g_signal_connect_swapped(G_OBJECT(polygon_draw),"activate",G_CALLBACK(draw_poly),NULL);
    draw_item=gtk_menu_item_new_with_label("Draw");
    //gtk_widget_set_size_request(GTK_WIDGET(draw_item),50,20);
    gtk_menu_item_set_submenu(GTK_MENU_ITEM(draw_item),draw_menu);
    return draw_item;
}
/*创建工具栏,由于在工具栏中的按钮的回调函数需要修改树视图和绘图区,
 * 所以将树视图和绘图区作为参数传递进来,以便回调函数参数传递
 * 输入参数:包含绘图区和树视图的结构体td
 * 输出参数:工具栏构件handlebox
 * 时间:2007-4-7修改*/
GtkWidget* create_toolbar(tree_drawing *td)
{
    GtkWidget *handlebox;
    GtkWidget *toolbar;
    GtkWidget *new_button,*import_button,*export_button,*quit_button;//工具按钮
    GtkWidget *zoom_out,*zoom_in;
    GtkWidget * iconw;

    handlebox=gtk_handle_box_new();
    toolbar=gtk_toolbar_new();    //设置工具栏格式
    gtk_toolbar_set_orientation (GTK_TOOLBAR (toolbar), GTK_ORIENTATION_HORIZONTAL);
    gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_BOTH);
    gtk_container_set_border_width (GTK_CONTAINER (toolbar), 5);
    new_button=gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),"New","Create a file","Private",NULL,GTK_SIGNAL_FUNC(create_file),td->tree_view);
    import_button=gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),"Import",
            "Import file","Private",NULL,GTK_SIGNAL_FUNC(import_file),td);   
    export_button=gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),"Export",
            "Export file","Private",NULL,GTK_SIGNAL_FUNC(export_file),td->tree_view);   
    iconw=gtk_image_new_from_file("enlarge.png");
    zoom_out=gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),NULL,"zoom out","Private",iconw,GTK_SIGNAL_FUNC(enlarge_obj),td->draw_area);
    gtk_toolbar_append_space(GTK_TOOLBAR(toolbar));
    iconw=gtk_image_new_from_file("deflate.png");
    zoom_in=gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),NULL,"zoom in","Private",iconw,GTK_SIGNAL_FUNC(deflate_obj),td->draw_area);
    quit_button=gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),"Quit",
            "Quit the file","Private",NULL,GTK_SIGNAL_FUNC(gtk_main_quit),NULL);   
    gtk_container_add(GTK_CONTAINER(handlebox),toolbar);
    return handlebox;
}
/*在绘图区中点击鼠标事件的回调函数,
 * 如果点击左键则按照绘图类型将鼠标处的坐标值处理后添加到链表prt中,并调用显示函数,显示图形;
 * 如果是鼠标右键,则将绘图类型设置为FALSE
 * 输入参数:事件盒构件本身event_box,事件:event,绘图区构件:data
 * 输出参数:TURE活FALSE,这个暂时没实际意义
 * 时间:2007-4-7修改*/
static gboolean button_press_callback(GtkWidget *event_box,GdkEventButton *event,GtkWidget *data)
{
   
    if(!draw_type)
    {
        return FALSE;
    }
    /*
if(event->button==2)
{
    gtk_menu_popup()
}   
*/
    if(event->button==3)
    {
        draw_type=FALSE;
    }
    int area_w=100,area_h=100;
    area_w=data->allocation.width;            //获得窗口尺寸
    area_h=data->allocation.height;
    if(event->button==1)
    {
        _2d_point *p=malloc(sizeof(_2d_point));
        p->x=((event->x-area_w/2)*width/area_w);
        p->y=((event->y-area_h/2)*height/area_h);
        prt=g_slist_append(prt,p);
        //printf("%f %f\t,%d,%d\n",p->x,p->y,area_w,area_h);
        GSList *iter1=NULL,*iter2=NULL;
        iter1=prt;
        iter2=prt->next;
        gdk_draw_point(GTK_WIDGET(data)->window,GTK_WIDGET(data)->style->
                fg_gc[GTK_WIDGET_STATE (event_box)],event->x,event->y);
        draw_prt(data);   
    }
    //gdk_drawable_unref(GTK_WIDGET(data)->window);
    return TRUE;
}
/*
static gboolean view_press(GtkWidget *widget,GdkEventButton *event,GtkWidget *menu)
{
      if(event->button==3)
    {
        gtk_menu_popup(GTK_MENU(widget),NULL,NULL,NULL,NULL,event->button,event->time);
    }
}*/
static gboolean
expose_event(GtkWidget *widget, GdkEventExpose *event,gpointer data)
{
    draw_prt(widget);
    return TRUE;
}
gint main(gint argc,char *argv[])
{
    GtkWidget *window;
    GtkWidget *file_item,*draw_item;    /*菜单项*/
    GtkWidget *menu_bar;            /*菜单*/
    GtkWidget *tool_bar;            /*工具栏*/
    GtkWidget *vbox,*hpaned;        /*竖直盒,水平分栏窗口*/
    GtkWidget *view,*event_box,*draw_area;
    GtkWidget *handle_box;            /*手柄构建,用于存放工具按钮*/
    gtk_init(&argc,&argv);
   
    window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window),"drawing window");
    g_signal_connect(G_OBJECT(window),"destroy",G_CALLBACK(gtk_main_quit),NULL);
    gtk_widget_set_size_request(GTK_WIDGET(window),500,400);
    gtk_container_set_border_width (GTK_CONTAINER (window), 10);
    vbox = gtk_vbox_new (FALSE, 0);            /*创建主竖直盒*/
    gtk_container_add (GTK_CONTAINER (window), vbox);
    gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);/*将窗口的显示位置设定为屏幕中央*/
    draw_area=gtk_drawing_area_new();/*由于这两个构件需要作为其它构件回调函数的参数,所以先在这里创建*/
    view=(GtkWidget*)create_tree();
    tree_drawing *td=malloc(sizeof(tree_drawing));/*定义结构体,以便回调函数调用*/
    td->tree_view=view;
    td->draw_area=draw_area;
    /*======================== 添加菜单 =====================================    */
    menu_bar = gtk_menu_bar_new ();
    gtk_box_pack_start(GTK_BOX(vbox),menu_bar,FALSE,FALSE,3);
    file_item=create_file_item(td);                //调用自定义创建菜单file的函数
    gtk_menu_bar_append (GTK_MENU_BAR (menu_bar), file_item);
    draw_item=create_draw_item();
    gtk_menu_bar_append(GTK_MENU_BAR(menu_bar),draw_item);
    /*
    GtkWidget *pop_up;
    pop_up=pop_menu(draw_area);
    */
    /*========================= 添加工具栏 =================================*/
    handle_box=create_toolbar(td);            /*调用自定义函数创建工具栏,由于工具栏中的按钮需要改变绘图区和树视图,所以需要将绘图区和树视图作为参数进行传递*/
    gtk_box_pack_start(GTK_BOX(vbox),handle_box,FALSE,FALSE,3);
    /*========================= 添加树视图 ==========================================*/
    hpaned=gtk_hpaned_new();            /*创建水平分栏窗口*/
    gtk_box_pack_start(GTK_BOX(vbox),hpaned,TRUE,TRUE,3);
    //g_signal_connect_swapped(G_OBJECT(view),"event",G_CALLBACK(view_press),pop_up);//添加右键菜单
    gtk_paned_add1(GTK_PANED(hpaned),view);
    /*========================== 添加绘图区 =========================================*/
    event_box=gtk_event_box_new();            //添加eventbox以便鼠标响应
    gtk_paned_add2(GTK_PANED(hpaned),event_box);
    gtk_container_add(GTK_CONTAINER(event_box),draw_area);
   
    /*-----------test - color------*/
    GdkColor color;
    color.red=55000;
    color.blue=55000;
    color.green=55000;
    gtk_widget_modify_bg(draw_area,GTK_STATE_NORMAL,&color);    /*设置背景颜色*/
    GdkColor colorf;
    colorf.red=0;
    colorf.blue=65535;
    colorf.green=0;
    gtk_widget_modify_fg(draw_area,GTK_STATE_NORMAL,&colorf);    /*设置前景颜色*/
    g_signal_connect(G_OBJECT(event_box),"button_press_event",G_CALLBACK(button_press_callback),draw_area);
    g_signal_connect(G_OBJECT(draw_area),"expose_event",G_CALLBACK(expose_event),NULL);
    //-----------------------------
    gtk_widget_show_all(window);
    width=draw_area->allocation.width;            /*获得绘图区尺寸,并赋值给全局变量width和height*/
    height=draw_area->allocation.height;   
    gtk_main();
    return 0;
}
阅读(4960) | 评论(0) | 转发(3) |
给主人留下些什么吧!~~