Logo Search packages:      
Sourcecode: sagcad version File versions  Download package

DrawArea.c

/* ====================================================================
 * ===  Copyright (C) 1998-2007 Yutaka Sagiya. All rights reserved. ===
 * ====================================================================
 * 
 *    Project              : SagCAD
 *    Description          : CAD/CAM
 *    Source               : DrawArea.c
 * 
 *    ----------------------------------
 * 
 *    License              : GNU General Public License (GPL)
 *    Copyright            : (C) 1998-2007 by Yutaka Sagiya
 *    email                : kappa@a6s.highway.ne.jp
 *                         : yutaka@sagiya.com
 *    Begin                : 2003/02/07
 *    Last                 : 2007/11/08
 * ====================================================================
 */

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif

#include <gtk/gtk.h>
#include <unistd.h>
//#include <pwd.h>
#include <sys/types.h>
#include <sys/stat.h>

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#include "MemoryLeak.h"
#include "List_cad.h"
#include "List_Dimension.h"
#include "List_PolyLine.h"
#include "List_Block.h"
#include "List_Undo.h"
#include "List_Select.h"
#include "global.h"
#include "Draw.h"
#include "Mouse.h"
#define _DRAWAREA_
#include "DrawArea.h"



/* ------------------------------------------------------------------
 * ドローイングエリア
 * expose (再描画) イベントハンドラ
 * 
 */
int expose_event(GtkWidget *widget, GdkEventExpose *event)
{
      gdk_draw_pixmap (widget->window, 
                               gc, 
                               pixmap, 
                               sagcad_system.DeviceX + event->area.x, sagcad_system.DeviceY + event->area.y,  
                               event->area.x, event->area.y,  
                               event->area.width, event->area.height);
      
      /* カーソル GDK_CROSS GDK_CROSSHAIR GDK_TCROSS */
      cursor = gdk_cursor_new (GDK_TCROSS);
      gdk_window_set_cursor (GTK_WIDGET(drawing_area)->window, cursor);

      return FALSE;
}



/* ------------------------------------------------------------------
 * ドローイングエリア
 * "scroll_event (スクロール)" イベントハンドラ
 */
gint scroll_event(GtkWidget *widget, GdkEventScroll *event, gpointer data)
{
      gint WithButton = 0, Button = 0;
      gint i_event = MOUSE_PRESS;

      if (event->direction == GDK_SCROLL_UP) {
            i_event = MOUSE_WHEEL_UP;
      } 
      else if (event->direction == GDK_SCROLL_DOWN) {
            i_event = MOUSE_WHEEL_DOWN;
      }

      MouseEvent(widget, 
                     (gpointer)event, 
                     i_event, 
                     Button, WithButton, 
                     (int) sagcad_system.DeviceX + event->x, 
                     (int) sagcad_system.DeviceY + event->y);

      return TRUE;
}



/* ------------------------------------------------------------------
 * ドローイングエリア
 * "motion_notify_event (ドラッグ)" イベントハンドラ
 */
int motion_notify_event(GtkWidget *widget, GdkEventMotion *event)
{
      int x, y;
      GdkModifierType state;
      char str[64];
      int Button = 0, Shift = 0;

      /* event の座標を調べる */
      if (event->is_hint) {
            gdk_window_get_pointer (event->window, &x, &y, &state);
            x = x + sagcad_system.DeviceX;
            y = y + sagcad_system.DeviceY;
      }
      else {
            x = sagcad_system.DeviceX + event->x;
            y = sagcad_system.DeviceY + event->y;
            state = event->state;
      }

      /* マウスの座標を表示 */
      sprintf(str, "x %.2f  ", ToViewX(x));
      gtk_label_set_text(GTK_LABEL(MouseX), str);

      sprintf(str, "y %.2f", ToViewY(y));
      gtk_label_set_text(GTK_LABEL(MouseY), str);

      if ((state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK) Shift = 1;
      if ((state & GDK_MOD1_MASK) == GDK_MOD1_MASK) Shift = 2;
      if ((state & GDK_CONTROL_MASK) == GDK_CONTROL_MASK) Shift = 4;

      /* 左ボタン */
      if ((state & GDK_BUTTON1_MASK) == GDK_BUTTON1_MASK) Button = 1;
      /* 中ボタン */
      if ((state & GDK_BUTTON2_MASK) == GDK_BUTTON2_MASK) Button = 4;
      /* 右ボタン */
      if ((state & GDK_BUTTON3_MASK) == GDK_BUTTON3_MASK) Button = 2;

      //g_print ("motion_notify_event : event  x = %d  y = %d\n", x, y);


//    SagCad_MouseMove(widget, Button, Shift, x, y);
      MouseEvent(widget, (gpointer)event, MOUSE_MOTION_NOTIFY, Button, Shift, x, y);


      return TRUE;
}



/* ------------------------------------------------------------------
 * ドローイングエリア
 * "button_press (クリック)" イベントハンドラ
 */
int button_press_event(GtkWidget *widget, GdkEventButton *event)
{
      int Shift = 0, Button = 0;

      if ((event->state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK) Shift = 1;
      if ((event->state & GDK_MOD1_MASK) == GDK_MOD1_MASK) Shift = 2;
      if ((event->state & GDK_CONTROL_MASK) == GDK_CONTROL_MASK) Shift = 4;

      /* 左ボタン */
      if (event->button == 1) Button = 1;
      /* 中ボタン */
      else if (event->button == 2) Button = 4;
      /* 右ボタン */
      else if (event->button == 3) Button = 2;
      /* ホイール上 */
      else if (event->button == 4) {
            ZoomUp();
            //Button = 8;
      }
      /* ホイール下 */
      else if (event->button == 5) {
            ZoomDown();
            //Button = 16;
      }

      //g_print ("button_press_event : event  x = %f  y = %f\n", event->x, event->y);
      //g_print("DrawArea.c : button_press_event() : in\n");


//    SagCad_MouseDown(widget, Button, Shift, (int) sagcad_system.DeviceX + event->x, (int) sagcad_system.DeviceY + event->y);
      MouseEvent(widget, (gpointer)event, MOUSE_PRESS, Button, Shift, sagcad_system.DeviceX + event->x, sagcad_system.DeviceY + event->y);


      return TRUE;
}



/* ------------------------------------------------------------------
 * ドローイングエリア
 * "release_event (リリース)" イベントハンドラ
 * 
 */
int button_release_event(GtkWidget *widget, GdkEventButton *event)
{
      int Shift = 0, Button = 0;

      if ((event->state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK) Shift = 1;
      if ((event->state & GDK_MOD1_MASK) == GDK_MOD1_MASK) Shift = 2;
      if ((event->state & GDK_CONTROL_MASK) == GDK_CONTROL_MASK) Shift = 4;

      /* 左ボタン */
      if (event->button == 1) Button = 1;
      /* 中ボタン */
      else if (event->button == 2) Button = 4;
      /* 右ボタン */
      else if (event->button == 3) Button = 2;

      //g_print ("button_release_event : event  x = %f  y = %f\n", event->x, event->y);


//    SagCad_MouseUp(widget, Button, Shift, sagcad_system.DeviceX + event->x, sagcad_system.DeviceX + event->y);
      MouseEvent(widget, (gpointer)event, MOUSE_RELEASE, Button, Shift, sagcad_system.DeviceX + event->x, sagcad_system.DeviceY + event->y);


      return TRUE;
}





int configure_event (GtkWidget *widget, GdkEventConfigure *event)
{
      if (sagcad_system.DeviceX == widget->allocation.width && sagcad_system.DeviceY == widget->allocation.height) {
            return 0;
      }


      /* ドローイングアレアの大きさ取得 */
      sagcad_system.DeviceX = widget->allocation.width;
      sagcad_system.DeviceY = widget->allocation.height;

      /* アスペクト比 */
      sagcad_system.Aspect = (double)sagcad_system.DeviceY / (double)sagcad_system.DeviceX;
      /* sagcad_system.ViewX をディスプレイの実際のサイズにする */
      //sagcad_system.ViewX = 200;//sagcad_system.DeviceX;
//    window_set();


      view_port_set(0, sagcad_system.DeviceY*3, sagcad_system.DeviceX*3, 0);
      world_window_set_center(Mag, MagX, MagY, sagcad_system.ViewX * 3);


      /* GC作成 */
      if (gc == NULL) {
            gc = create_gc(widget);
      }

      if (pixmap) {
            gdk_pixmap_unref (pixmap);
      }

      pixmap = gdk_pixmap_new (widget->window, 
                                           widget->allocation.width * 3, 
                                           widget->allocation.height * 3, 
                                           -1);

      PenSet(gc, 1, sagcad_color.Back);
      gdk_draw_rectangle (pixmap, gc, TRUE, 0, 0, widget->allocation.width * 3, widget->allocation.height * 3);

//g_print("DrawArea.c : configure_event() : Draw\n");
      Draw(widget);


      return TRUE;
}





/* ------------------------------------------------------------------
 * ドローイングエリアの生成
 * 
 */
GtkWidget *create_drawing_area(void)
{
      GtkWidget *drawing_area;

      /* ドローイングエリア生成 */
      drawing_area = gtk_drawing_area_new();
      /* ドローイングエリアのサイズ設定 */
      gtk_widget_set_size_request( GTK_WIDGET(drawing_area), PICTURE_WIDTH, PICTURE_HEIGHT);

      /* "configure_event"イベントハンドラ設定 */
      g_signal_connect(G_OBJECT(drawing_area), "configure_event",
                         G_CALLBACK(configure_event), NULL);
      /* "expose_event"イベントハンドラ設定 */
      g_signal_connect(G_OBJECT(drawing_area), "expose_event",
                         G_CALLBACK(expose_event), NULL);
      /* "motion_notify_event"イベントハンドラ設定 */
      g_signal_connect(G_OBJECT(drawing_area), "motion_notify_event",
                         G_CALLBACK(motion_notify_event), NULL);
      /* "button_press_event"イベントハンドラ設定 */
      g_signal_connect(G_OBJECT(drawing_area), "button_press_event",
                         G_CALLBACK(button_press_event), NULL);
      /* "button_release_event"イベントハンドラ設定 */
      g_signal_connect(G_OBJECT(drawing_area), "button_release_event",
                         G_CALLBACK(button_release_event), NULL);
      /* "scroll_event"イベントハンドラ設定 */
      g_signal_connect(G_OBJECT(drawing_area), "scroll_event",
                         G_CALLBACK(scroll_event), NULL);
      /* イベントマスク設定 */
      gtk_widget_set_events(drawing_area,  GDK_EXPOSURE_MASK
                                                             | GDK_LEAVE_NOTIFY_MASK
                                                             | GDK_BUTTON_PRESS_MASK
                                                             | GDK_BUTTON_RELEASE_MASK
                                                             | GDK_POINTER_MOTION_MASK
                                                             | GDK_POINTER_MOTION_HINT_MASK
                                                             | GDK_SCROLL_MASK);


      /* カーソル */
      //cursor = gdk_cursor_new (GDK_CROSSHAIR);
      //gdk_window_set_cursor (GTK_WIDGET(drawing_area)->window, cursor);

      return drawing_area;
}





/* ====================================================================
 * ===  Copyright (C) 1998-2007 Yutaka Sagiya. All rights reserved. ===
 * ====================================================================
 *    Project              : SagCAD
 *    Source               : DrawArea.c
 * ====================================================================
 */





gint Pan(GtkWidget *widget, gint event, gint Button, gint WithButton, gint x, gint y)
{
      static gint press_x = 0, press_y = 0;
      gint dx, dy;


      if (event == MOUSE_PRESS) {
            press_x = x;
            press_y = y;
            return 0;
      }

      else if (event == MOUSE_MOTION_NOTIFY) {
            if (press_x != 0 && press_y != 0) {
                  dx = x - press_x;
                  dy = y - press_y;
                  
                  gdk_draw_pixmap (widget->window,                      // drawable : GdkDrawable (GdkWindow または GdkPixmap) 
                                           gc,        // gc       : GdkGC 
                                           pixmap,    // src      : 描画する GdkPixmap 
                                           sagcad_system.DeviceX - dx, // xsrc     : src 全体を囲む矩形領域の左端の X座標 
                                           sagcad_system.DeviceY - dy, // ysrc     : src 全体を囲む矩形領域の上端の Y座標 
                                           0, // xdest    : drawable を囲む矩形領域の X座標 
                                           0, // ydest    : drawable を囲む矩形領域の Y座標 
                                           sagcad_system.DeviceX,                   // width    : 描画する領域の幅 
                                           sagcad_system.DeviceY);                  // height   : 描画する領域の高さ 
            return 0;
            }
      }

      else if (event == MOUSE_RELEASE) {
            dx = x - press_x;
            dy = y - press_y;


            
            if (dx == 0 && dy == 0) return 1;
            


            MagX = MagX - (ToViewX(dx) - ToViewX(0));
            MagY = MagY - (ToViewY(dy) - ToViewY(0));
            SetMag(Mag);
            
            /* 再描画 */
            Redraw();
            press_x = 0;
            press_y = 0;
            return 0;
      }
      return 0;
}





/* --------------------------------------------------------------------------
 * NAME: 
 *     MouseEvent
 * 
 * DESCRIPTION:
 *     MouseEvent
 * 
 * PARAMS: 
 *     GtkWidget *widget        
 *     gint event               
 *         MOUSE_MOTION_NOTIFY
 *         MOUSE_PRESS
 *         MOUSE_RELEASE
 *         MOUSE_WHEEL_UP
 *         MOUSE_WHEEL_DOWN
 *     gint Button              
 *         MOUSE_PRESS_LEFT
 *         MOUSE_PRESS_CENTER
 *         MOUSE_PRESS_RIGHT
 *     gint WithButton          
 *         MOUSE_WITH_SHIFT
 *         MOUSE_WITH_ALT
 *         MOUSE_WITH_CONTROL
 *     gint x                   
 *     gint y                   
 * 
 * RETURN VALUE:
 *     正常終了               LIST *
 *     異常終了               NULL
 * 
 * USAGE: 
 * --------------------------------------------------------------------------
 */
gint MouseEvent(GtkWidget *widget, GdkEvent *event, gint i_event, gint Button, gint WithButton, gint x, gint y)
{
      /* 右ボタンドラッグでパン Pan */
      if (Button == 4) {
            if (Pan(widget, i_event, Button, WithButton, x, y) == 1) {
                  SagCad_MouseDown(widget, Button, WithButton, x, y);
            }
      }

      if (i_event == MOUSE_WHEEL_UP) {
            ZoomUp();
      }
      if (i_event == MOUSE_WHEEL_DOWN) {
            ZoomDown();
      }


      if (i_event == MOUSE_PRESS && Button != 4) {
            SagCad_MouseDown(widget, Button, WithButton, x, y);
      }

      if (i_event == MOUSE_MOTION_NOTIFY) {
            SagCad_MouseMove(widget, Button, WithButton, x, y);
      }

      if (i_event == MOUSE_RELEASE) {
            SagCad_MouseUp(widget, Button, WithButton, x, y);
      }




      return 0;
}




Generated by  Doxygen 1.6.0   Back to index