Chinaunix首页 | 论坛 | 博客
  • 博客访问: 37903
  • 博文数量: 13
  • 博客积分: 1400
  • 博客等级: 上尉
  • 技术积分: 158
  • 用 户 组: 普通用户
  • 注册时间: 2009-04-05 19:31
文章分类

全部博文(13)

文章存档

2011年(1)

2009年(12)

我的朋友

分类: LINUX

2009-05-16 19:08:00

wm.c image.c 为范本,wm.c 执行后在画面上只会看到图片图(没有窗口标题列与边框),并且可使用鼠标来拖曳图片。本范例主要在展示以下的 Nano-X API 程序设计方法:

˙ 如何设定窗口属性(window manager)。
˙
如何与使用者做互动(human interactive)。

要写出「托曳图片」的功能,首先必须把窗口的标题列与边框去除,否则只能在标题列上托曳整个「窗口」。做法非常简单,只要在建立窗口时设定 window manager 即可:

   wid = GrNewWindowEx(GR_WM_PROPS_APPWINDOW |

                       GR_WM_PROPS_NODECORATE |

                       GR_WM_PROPS_NOAUTOMOVE,

                       NULL,

                       GR_ROOT_WINDOW_ID,

                       0, 0,

                       image_jollen.width, /* 图片宽度 */

                       image_jollen.height /* 图片高度 */,

                       0xFFFFFF);

粗体字的地方是新加入的 window manager 属性,为了达到我们的要求,我们指定了3个属性值:

·  GR_WM_PROPS_APPWINDOW:使用 window manager 的外观。

·  GR_WM_PROPS_NODECORATE:不要有窗口边框。

·  GR_WM_PROPS_NOAUTOMOVE:第一次显示窗口时不移动窗口。

由于我们并未指定 GR_WM_PROPS_CAPTION,因此不会有窗口标题列。在处理使用者互动上,我们需要自行处理3个鼠标事件:

·  GR_EVENT_MASK_MOUSE_POSITION:鼠标移动事件。

·  GR_EVENT_MASK_BUTTON_UP:放开鼠标按键。

·  GR_EVENT_MASK_BUTTON_DOWN:按下鼠标按键。

因此选择事件的程序代码应修改成:

   GrSelectEvents(wid, GR_EVENT_MASK_MOUSE_POSITION |

                           GR_EVENT_MASK_BUTTON_UP |

                           GR_EVENT_MASK_BUTTON_DOWN);

接下来,要特别注意的地方是「显示图片的时机」。我们在这里设计成在窗口显示后、进入 event loop 处理。首先是显示图片的程序写法:

   GrMapWindow(wid);

   GrDrawImageBits(wid, gc, 0, 0, &image_jollen);

接着,修改 event loop,并加上处理以上 3 个事件(粗体字部份)的程序代码:

void event_handler (GR_EVENT *event)

{

   switch (event->type)

   {

      case GR_EVENT_TYPE_CLOSE_REQ:

            GrClose();

      case GR_EVENT_TYPE_MOUSE_POSITION:

            position_event(&event->mouse);

            break;

      case GR_EVENT_TYPE_BUTTON_UP:

      case GR_EVENT_TYPE_BUTTON_DOWN:

            button_event(&event->button);

            break;

      default: break;

   }

}

对于鼠标按键的处理方式为:当鼠标被按下时,便记录鼠标的新坐标,然后将窗口移到最上层;若此时使用者移动鼠标,则将整个「窗口」移到新坐标位置。如此一来,使用者就会看到「整个图片被托曳」的效果。

处理鼠标按键的程序写法如下:

void button_event(GR_EVENT_BUTTON *e)

{

   if (e->type == GR_EVENT_TYPE_BUTTON_DOWN) {

      newx = e->x;

      newy = e->y;

 

      button_down = 1;

      GrRaiseWindow(e->wid);

   } else {

      button_down = 0;

   }

}

先判断目前所产生的事件是否为 GR_EVENT_TYPE_BUTTON_DOWN;如果是,才记录新坐标,并将 button_down 设为 1。若不是 GR_EVENT_TYPE_BUTTON_DOWN 事件,表示鼠标按键已放开,此时将 button_down 设为 0
处理鼠标移动事件的程序写法如下:

void position_event(GR_EVENT_MOUSE *e)

{

   if (!button_down) return;

 

   GrMoveWindow(e->wid, e->rootx-newx, e->rooty-newy);

}

先判断 button_down 是否为 false,若 button_down等于0,表示鼠标按键是放开的,因此不做任何动作。反正,若 button_down true,代表鼠标按键仍「持续」按住,此时才能呼叫 GrMoveWindow() 移动窗口。

以下是 wm.c 的完整程序,粗体字是新加入或修改过的程序代码。

/*

 * Copyright(c) 2003,2004

 *

 * - Nano-X API example.

 * - wm.c

 *

 */

 

#include

#define MWINCLUDECOLORS

#include

#include

 

GR_WINDOW_ID wid;

GR_GC_ID gc;

 

/* 外部影像 */

extern GR_IMAGE_HDR image_jollen;

 

void event_handler (GR_EVENT *event);

 

/* 鼠标坐标 */

int newx, newy;

int button_down;

 

int main (void)

{

   if (GrOpen() < 0) {

        fprintf (stderr, "GrOpen failed");

        return -1;

   }

 

   gc = GrNewGC();

   GrSetGCForeground (gc, 0xFF0000);

 

   wid = GrNewWindowEx(GR_WM_PROPS_APPWINDOW |

                       GR_WM_PROPS_NODECORATE |

                       GR_WM_PROPS_NOAUTOMOVE,

                       NULL,

                       GR_ROOT_WINDOW_ID,

                       0, 0,

                       image_jollen.width, /* 影像宽度 */

                       image_jollen.height /* 影像高度 */,

                       0xFFFFFF);

 

   GrSelectEvents(wid, GR_EVENT_MASK_MOUSE_POSITION |

                    GR_EVENT_MASK_BUTTON_UP |

                    GR_EVENT_MASK_BUTTON_DOWN);

 

   GrMapWindow(wid);

   GrDrawImageBits(wid, gc, 0, 0, &image_jollen);

 

   GrMainLoop(event_handler);

 

   return 0;

}

 

void button_event(GR_EVENT_BUTTON *e)

{

   if (e->type == GR_EVENT_TYPE_BUTTON_DOWN) {

      newx = e->x;

      newy = e->y;

 

      button_down = 1;

      GrRaiseWindow(e->wid);

   } else {

      button_down = 0;

   }

}

 

void position_event(GR_EVENT_MOUSE *e)

{

   if (!button_down) return;

 

   GrMoveWindow(e->wid, e->rootx-newx, e->rooty-newy);

}

 

void event_handler (GR_EVENT *event)

{

   switch (event->type)

   {

      case GR_EVENT_TYPE_CLOSE_REQ:

                  GrClose();

      case GR_EVENT_TYPE_MOUSE_POSITION:

                  position_event(&event->mouse);

                  break;

      case GR_EVENT_TYPE_BUTTON_UP:

      case GR_EVENT_TYPE_BUTTON_DOWN:

           button_event(&event->button);

                  break;

      default: break;

   }

}

阅读(936) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~