Problem mit DrawingArea in Gtkmm



  • Hallo, ich programmiere gerade ein kleines Paintprogramm und nutze dazu die Drawingarea. Ich lade dann ein Bild und lasse es anzeigen. Nun möchte ich einen Breich markieren/auswählen (so eine art Maske), aber das funktioniert nicht so richtig. Kann mir da jemand helfen.

    hier der Code der Klasse:

    #include <iostream>
    #include <sstream>
    #include <gtkmm/image.h>
    #include "Imagebox.h"
    
    Imagebox::Imagebox(int xSize, int ySize)
    {
      Glib::RefPtr<Gdk::Colormap> colormap = get_default_colormap();
    
      black_ = Gdk::Color("black");
      white_ = Gdk::Color("white");
      grey_ = Gdk::Color("grey");
      red_ = Gdk::Color("red");
      blue_ = Gdk::Color("blue");
    
      colormap->alloc_color(black_);
      colormap->alloc_color(white_);
      colormap->alloc_color(grey_);
      colormap->alloc_color(red_);
      colormap->alloc_color(blue_);
    
      x_Size = xSize; y_Size = ySize;
      lMouseClicked = false;
      mMouseClicked = false;
      rMouseClicked = false;
      drawing = false;
    
      set_events( Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK );
    
      signal_motion_notify_event().connect(sigc::mem_fun( *this, &Imagebox::on_area_motion_notify_event) );
      signal_button_press_event().connect(sigc::mem_fun( *this, &Imagebox::on_area_button_press_event) );
      signal_button_release_event().connect(sigc::mem_fun( *this, &Imagebox::on_area_button_release_event) );
    
      buff = NULL;
    }
    
    Imagebox::~Imagebox()
    {
    
    }
    
    void Imagebox::LoadPic(const std::string filename, unsigned char *picBuffer)
    {
      FILE  *stream;
    
      if ( (stream  = fopen( (char*)filename.c_str() , "rb" )) == NULL )
        {
          std::cout<<"error while open file "<<filename<<std::endl;
        }
      else
       {
         // read the data from RAW input file
         fread( picBuffer, 1392 * 1040, 1, stream );
         fclose(stream);
       }
    }
    
    bool Imagebox::on_area_motion_notify_event(GdkEventMotion* event)
    {
      std::ostringstream tmp;
    
      if (event)
        {
    
    //      hruler->property_position().set_value(event->x);
    //      vruler->property_position().set_value(event->y);
          tmp<<event->x<<","<<event->y;
          label_xypos->set_text( tmp.str() );
    
          if ( lMouseClicked )
            {
              switch ( *tool )
              {
                case 1:
                {
                  gc02->set_line_attributes(2,Gdk::LINE_ON_OFF_DASH,Gdk::CAP_NOT_LAST,Gdk::JOIN_MITER);
    //            gc01->set_line_attributes(2,Gdk::LINE_SOLID,Gdk::CAP_NOT_LAST,Gdk::JOIN_MITER);
                  xpos = (int)event->x;
                  ypos = (int)event->y;
                  if (lastx != xpos || lasty != ypos)
                    {
                      // erase old rectangle
                      gc02->set_foreground(white_);
                      window->draw_rectangle(gc02,false,startx,starty,lastx-startx,lasty-starty);
                      //  window->draw_image(gc01,image,xpos-startx,ypos-starty,xpos-startx,ypos-starty);
                      // draw new rectangle
                      gc02->set_foreground(red_);
                      window->draw_rectangle(gc02,false,startx,starty,xpos-startx,ypos-starty);
    //                  image = window->get_image (startx+1,starty+1,xpos-startx-1,ypos-starty-1);
    
                      lastx = xpos;
                      lasty = ypos;
                    }
                  break;
                }
                case 2:
                {
                  gc02->set_line_attributes(2,Gdk::LINE_SOLID,Gdk::CAP_NOT_LAST,Gdk::JOIN_MITER);
                  xpos = (int)event->x;
                  ypos = (int)event->y;
                  gc02->set_foreground(red_);
                  draw_brush(xpos,ypos);
                  break;
                }
                default: break;
              }// switch
            }
          else
            {
            }
          if ( mMouseClicked )
            {
            }
          if ( rMouseClicked )
            {
            }
        }
    
      return true;
    }
    
    bool Imagebox::on_area_button_press_event(GdkEventButton* event)
    {
      if ( event->type == GDK_BUTTON_PRESS )
        {
          /* linke Maustaste */
          if ( event->button == 1 )
            {
              lMouseClicked = true;
              startx = (int)event->x;
              starty  = (int)event->y;
              lastx = startx;
              lasty = starty;
              drawing = true;
            }
          /* mittlere Maustaste */
          if ( event->button == 2 )
            {
              mMouseClicked = true;
            }
          /* rechte Maustaste */
          if ( event->button == 3 )
            {
              rMouseClicked = true;
            }
        }
      return false;
    }
    
    bool Imagebox::on_area_button_release_event(GdkEventButton* event)
    {
      if ( event->type == GDK_BUTTON_RELEASE )
        {
          /* linke Maustaste */
          if ( event->button == 1 )
            {
              lMouseClicked = false;
              drawing = true;
    
    //        image = window->get_image (startx+1,starty+1,xpos-1,ypos-1);
              window->draw_image(gc01,image,startx+1,starty+1,startx+1,starty+1,(xpos-1)-(startx+1),(ypos-1)-(starty+1));
    /*
              std::cout<<"x"<<xpos<<std::endl;
              std::cout<<"y"<<ypos<<std::endl;
              std::cout<<"lx"<<lastx<<std::endl;
              std::cout<<"ly"<<lasty<<std::endl;
              std::cout<<"sx"<<startx<<std::endl;
              std::cout<<"sy"<<starty<<std::endl;
    */
            }
          /* mittlere Maustaste */
          if ( event->button == 2 )
            {
              mMouseClicked = false;
            }
          /* rechte Maustaste */
          if ( event->button == 3 )
            {
              rMouseClicked = false;
            }
        }
      return false;
    }
    
    void Imagebox::on_realize()
    {
      Gtk::DrawingArea::on_realize();
    
      window = get_window();
    
      gc01 = Gdk::GC::create(window);
      gc02 = Gdk::GC::create(window);
    
      window->resize( x_Size, y_Size );
      window->set_background(white_);
      window->clear();
    }
    
    bool Imagebox::on_expose_event(GdkEventExpose* event)
    {
      int winx, winy, winw,winh,wind;
      window = get_window();
    
      window->get_geometry(winx,winy,winw,winh,wind);
    
      image = window->get_image (0,0,x_Size,y_Size);
    
      if ( buff != NULL)
        {
          window->draw_gray_image(gc01,0,0,w,h,Gdk::RGB_DITHER_NONE,buff,1*w);
        }
    
    //  window->draw_image(gc01,image,0,0,0,0,image->get_width(),image->get_height());
    
      return true;
    }
    
    void Imagebox::draw_brush(gdouble x, gdouble y)
    {
      window->draw_rectangle(gc02,true,(int)x-5,(int)y-5,10,10);
    }
    
    void Imagebox::push_picture(unsigned char *buffer, unsigned int nWidth, unsigned int nHeight)
    {
      buff = buffer;
      w = nWidth;
      h = nHeight;
      window->draw_gray_image(gc01,0,0,nWidth,nHeight,Gdk::RGB_DITHER_NONE,buffer,1*nWidth);
    }
    

Anmelden zum Antworten