Chinaunix首页 | 论坛 | 博客
  • 博客访问: 34777
  • 博文数量: 23
  • 博客积分: 1415
  • 博客等级: 上尉
  • 技术积分: 235
  • 用 户 组: 普通用户
  • 注册时间: 2009-02-20 09:41
文章分类
文章存档

2011年(1)

2010年(2)

2009年(20)

我的朋友

分类:

2009-09-26 02:48:30

1. Gtk::DrawArea 配合 Cairo::Context 可以画图。

#include <cairomm/context.h>
#include <gtkmm/drawingarea.h>

class MyArea : public Gtk::DrawingArea
{
    public:
        MyArea(){
                // This is where we draw on the window
              Glib::RefPtr<Gdk::Window> window = get_window();
              if(window)
              {
               Gtk::Allocation allocation = get_allocation();
               const int width = allocation.get_width();
               const int height = allocation.get_height();

               // coordinates for the center of the window
               int xc, yc;
               xc = width / 2;
               yc = height / 2;

               Cairo::RefPtr<Cairo::Context> cr = window->create_cairo_context();
               cr->set_line_width(10.0);

               // clip to the area indicated by the expose event so that we only redraw
               // the portion of the window that needs to be redrawn
               cr->rectangle(event->area.x, event->area.y,
               event->area.width, event->area.height);
               cr->clip();

               // draw red lines out from the center of the window
               cr->set_source_rgb(0.8, 0.0, 0.0);
               cr->move_to(0, 0);
               cr->line_to(xc, yc);
               cr->line_to(0, height);
               cr->move_to(xc, yc);
               cr->line_to(width, yc);
               cr->stroke();
              }

              return true;
            
        }
    protected:
        //Override default signal handler:
        virtual bool on_expose_event(GdkEventExpose* event);
}


2. 接上 到 cr->clip后:

    cr->save();
    cr->arc(width / 3.0, height / 4.0, lesser / 4.0, -(M_PI / 5.0), M_PI);
    cr->close_path(); // line back to start point

    cr->set_source_rgb(0.0, 0.8, 0.0);
    cr->fill_preserve();
    cr->restore(); // back to opaque black

    cr->stroke(); // outline it


    // now draw a circle

    cr->save();
    cr->arc(xc, yc, lesser / 4.0, 0.0, 2.0 * M_PI); // full circle

    cr->set_source_rgba(0.0, 0.0, 0.8, 0.6); // partially translucent

    cr->fill_preserve();
    cr->restore(); // back to opaque black

    cr->stroke();

    // and finally an ellipse

    double ex, ey, ew, eh;
    // center of ellipse

    ex = xc;
    ey = 3.0 * height / 4.0;
    // ellipse dimensions

    ew = 3.0 * width / 4.0;
    eh = height / 3.0;

    cr->save();

    cr->translate(ex, ey); // make (ex, ey) == (0, 0)

    cr->scale(ew / 2.0, eh / 2.0); // for width: ew / 2.0 == 1.0

                                    // for height: eh / 2.0 == 1.0


    cr->arc(0.0, 0.0, 1.0, 0.0, 2 * M_PI); // 'circle' centered at (0, 0)

                                            // with 'radius' of 1.0


    cr->set_source_rgba(0.8, 0.0, 0.0, 0.7);
    cr->fill_preserve();
    cr->restore(); // back to opaque black

    cr->stroke();


3. 时钟


#include <ctime>
#include <cmath>
#include <cairomm/context.h>
#include "clock.h"

Clock::Clock()
: m_radius(0.42), m_line_width(0.05)
{
  Glib::signal_timeout().connect( sigc::mem_fun(*this, &Clock::on_timeout), 5000 );

  #ifndef GLIBMM_DEFAULT_SIGNAL_HANDLERS_ENABLED
  //Connect the signal handler if it isn't already a virtual method override:

  signal_expose_event().connect(sigc::mem_fun(*this, &Clock::on_expose_event), false);
  #endif //GLIBMM_DEFAULT_SIGNAL_HANDLERS_ENABLED

}

Clock::~Clock()
{
}

bool Clock::on_expose_event(GdkEventExpose* event)
{
  // This is where we draw on the window

  Glib::RefPtr<Gdk::Window> window = get_window();
  if(window)
  {
    Gtk::Allocation allocation = get_allocation();
    const int width = allocation.get_width();
    const int height = allocation.get_height();

    Cairo::RefPtr<Cairo::Context> cr = window->create_cairo_context();

    if(event)
    {
        // clip to the area indicated by the expose event so that we only

        // redraw the portion of the window that needs to be redrawn

        cr->rectangle(event->area.x, event->area.y,
                event->area.width, event->area.height);
        cr->clip();
    }

    // scale to unit square and translate (0, 0) to be (0.5, 0.5), i.e.

    // the center of the window

    cr->scale(width, height);
    cr->translate(0.5, 0.5);
    cr->set_line_width(m_line_width);

    cr->save();
    cr->set_source_rgba(0.337, 0.612, 0.117, 0.9); // green

    cr->paint();
    cr->restore();
    cr->arc(0, 0, m_radius, 0, 2 * M_PI);
    cr->save();
    cr->set_source_rgba(1.0, 1.0, 1.0, 0.8);
    cr->fill_preserve();
    cr->restore();
    cr->stroke_preserve();
    cr->clip();

    //clock ticks

    for (int i = 0; i < 12; i++)
    {
        double inset = 0.05;

        cr->save();
        cr->set_line_cap(Cairo::LINE_CAP_ROUND);

        if(i % 3 != 0)
        {
            inset *= 0.8;
            cr->set_line_width(0.03);
        }

        cr->move_to(
                (m_radius - inset) * cos (i * M_PI / 6),
                (m_radius - inset) * sin (i * M_PI / 6));
        cr->line_to (
                m_radius * cos (i * M_PI / 6),
                m_radius * sin (i * M_PI / 6));
        cr->stroke();
        cr->restore(); /* stack-pen-size */
    }

    // store the current time

    time_t rawtime;
    time(&rawtime);
    struct tm * timeinfo = localtime (&rawtime);

    // compute the angles of the indicators of our clock

    double minutes = timeinfo->tm_min * M_PI / 30;
    double hours = timeinfo->tm_hour * M_PI / 6;
    double seconds= timeinfo->tm_sec * M_PI / 30;

    cr->save();
    cr->set_line_cap(Cairo::LINE_CAP_ROUND);

    // draw the seconds hand

    cr->save();
    cr->set_line_width(m_line_width / 3);
    cr->set_source_rgba(0.7, 0.7, 0.7, 0.8); // gray

    cr->move_to(0, 0);
    cr->line_to(sin(seconds) * (m_radius * 0.9),
            -cos(seconds) * (m_radius * 0.9));
    cr->stroke();
    cr->restore();

    // draw the minutes hand

    cr->set_source_rgba(0.117, 0.337, 0.612, 0.9); // blue

    cr->move_to(0, 0);
    cr->line_to(sin(minutes + seconds / 60) * (m_radius * 0.8),
            -cos(minutes + seconds / 60) * (m_radius * 0.8));
    cr->stroke();

    // draw the hours hand

    cr->set_source_rgba(0.337, 0.612, 0.117, 0.9); // green

    cr->move_to(0, 0);
    cr->line_to(sin(hours + minutes / 12.0) * (m_radius * 0.5),
            -cos(hours + minutes / 12.0) * (m_radius * 0.5));
    cr->stroke();
    cr->restore();

    // draw a little dot in the middle

    cr->arc(0, 0, m_line_width / 3.0, 0, 2 * M_PI);
    cr->fill();

  }

  return true;
}


bool Clock::on_timeout()
{
    // force our program to redraw the entire clock.

    Glib::RefPtr<Gdk::Window> win = get_window();
    if (win)
    {
        Gdk::Rectangle r(0, 0, get_allocation().get_width(),
                get_allocation().get_height());
        win->invalidate_rect(r, false);
    }
    return true;
}


4. line join:

cr->scale(width, height);
    cr->save();
    cr->set_source_rgb(1, 1, 1);
    cr->paint();
    cr->restore();
    cr->set_line_width(0.12);
    cr->move_to(0.3, 0.3);
    cr->rel_line_to(0.2, -0.2);
    cr->rel_line_to(0.2, 0.2);
    cr->set_line_join(Cairo::LINE_JOIN_MITER); /* def ault */
    cr->stroke();
    cr->move_to(0.3, 0.6);
    cr->rel_line_to(0.2, -0.2);
    cr->rel_line_to(0.2, 0.2);
    cr->set_line_join(Cairo::LINE_JOIN_BEVEL);
    cr->stroke();
    cr->move_to(0.3, 0.9);
    cr->rel_line_to(0.2, -0.2);
    cr->rel_line_to(0.2, 0.2);
    cr->set_line_join(Cairo::LINE_JOIN_ROUND);
    cr->stroke();


阅读(969) | 评论(0) | 转发(0) |
0

上一篇:Gtk::Dialog

下一篇:button

给主人留下些什么吧!~~