#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;
}