1
0
Fork 0
mirror of https://github.com/ruby-opencv/ruby-opencv synced 2023-03-27 23:22:12 -04:00

fixed Window to handle MouseEvent with propriety

This commit is contained in:
ser1zw 2011-05-05 04:24:21 +09:00
parent 6be99de63c
commit 81714f0768
8 changed files with 182 additions and 59 deletions

View file

@ -117,7 +117,7 @@ VALUE rb_event(VALUE self)
VALUE
rb_left_button_q(VALUE self)
{
return MOUSEEVENT(self)->flag & CV_EVENT_FLAG_LBUTTON ? Qtrue : Qfalse;
return MOUSEEVENT(self)->flags & CV_EVENT_FLAG_LBUTTON ? Qtrue : Qfalse;
}
/*
@ -126,7 +126,7 @@ rb_left_button_q(VALUE self)
VALUE
rb_right_button_q(VALUE self)
{
return MOUSEEVENT(self)->flag & CV_EVENT_FLAG_RBUTTON ? Qtrue : Qfalse;
return MOUSEEVENT(self)->flags & CV_EVENT_FLAG_RBUTTON ? Qtrue : Qfalse;
}
/*
@ -135,7 +135,7 @@ rb_right_button_q(VALUE self)
VALUE
rb_middle_button_q(VALUE self)
{
return MOUSEEVENT(self)->flag & CV_EVENT_FLAG_MBUTTON ? Qtrue : Qfalse;
return MOUSEEVENT(self)->flags & CV_EVENT_FLAG_MBUTTON ? Qtrue : Qfalse;
}
/*
@ -144,7 +144,7 @@ rb_middle_button_q(VALUE self)
VALUE
rb_ctrl_key_q(VALUE self)
{
return MOUSEEVENT(self)->flag & CV_EVENT_FLAG_CTRLKEY ? Qtrue : Qfalse;
return MOUSEEVENT(self)->flags & CV_EVENT_FLAG_CTRLKEY ? Qtrue : Qfalse;
}
/*
@ -153,7 +153,7 @@ rb_ctrl_key_q(VALUE self)
VALUE
rb_shift_key_q(VALUE self)
{
return MOUSEEVENT(self)->flag & CV_EVENT_FLAG_SHIFTKEY ? Qtrue : Qfalse;
return MOUSEEVENT(self)->flags & CV_EVENT_FLAG_SHIFTKEY ? Qtrue : Qfalse;
}
/*
@ -162,18 +162,18 @@ rb_shift_key_q(VALUE self)
VALUE
rb_alt_key_q(VALUE self)
{
return MOUSEEVENT(self)->flag & CV_EVENT_FLAG_ALTKEY ? Qtrue : Qfalse;
return MOUSEEVENT(self)->flags & CV_EVENT_FLAG_ALTKEY ? Qtrue : Qfalse;
}
VALUE
new_object(int flag, int y, int x, int event)
new_object(int event, int x, int y, int flags)
{
VALUE object = rb_allocate(rb_class());
MouseEvent *mouseevent = MOUSEEVENT(object);
mouseevent->point.x = x;
mouseevent->point.y = y;
mouseevent->event = event;
mouseevent->flag = flag;
mouseevent->flags = flags;
return object;
}

View file

@ -24,7 +24,7 @@ __NAMESPACE_BEGIN_MOUSEEVENT
typedef struct MouseEvent {
CvPoint point;
int event;
int flag;
int flags;
} MouseEvent;
VALUE rb_class();

View file

@ -409,6 +409,9 @@ define_ruby_module()
rb_define_const(rb_module, "CV_FM_8POINT", INT2FIX(CV_FM_8POINT));
rb_define_const(rb_module, "CV_FM_RANSAC", INT2FIX(CV_FM_RANSAC));
rb_define_const(rb_module, "CV_FM_LMEDS", INT2FIX(CV_FM_LMEDS));
/* Flags of window */
rb_define_const(rb_module, "CV_WINDOW_AUTOSIZE", INT2FIX(CV_WINDOW_AUTOSIZE));
VALUE inversion_method = rb_hash_new();
/* {:lu, :svd, :svd_sym(:svd_symmetric)}: Inversion method */

View file

@ -30,8 +30,7 @@ GET_WINDOW_NAME(VALUE object)
void *handle = DATA_PTR(object);
if (!handle)
rb_raise(rb_eStandardError, "window handle error");
const char *window_name = cvGetWindowName(handle);
return window_name;
return (const char*)cvGetWindowName(handle);
}
st_table *windows = st_init_numtable();
@ -64,10 +63,10 @@ define_ruby_class()
rb_define_singleton_method(rb_klass, "destroy_all", RUBY_METHOD_FUNC(rb_destroy_all), 0);
rb_define_method(rb_klass, "resize", RUBY_METHOD_FUNC(rb_resize), -1);
rb_define_method(rb_klass, "move", RUBY_METHOD_FUNC(rb_move), -1);
rb_define_method(rb_klass, "show_image", RUBY_METHOD_FUNC(rb_show_image), 1);
rb_define_method(rb_klass, "show_image", RUBY_METHOD_FUNC(rb_show_image), -1);
rb_define_alias(rb_klass, "show", "show_image");
rb_define_method(rb_klass, "set_trackbar", RUBY_METHOD_FUNC(rb_set_trackbar), -1);
rb_define_method(rb_klass, "set_mouse_callback", RUBY_METHOD_FUNC(rb_set_mouse_callback), 0);
rb_define_method(rb_klass, "set_mouse_callback", RUBY_METHOD_FUNC(rb_set_mouse_callback), -1);
rb_define_alias(rb_klass, "on_mouse", "set_mouse_callback");
}
@ -121,34 +120,26 @@ rb_aref(VALUE klass, VALUE name)
/*
* call-seq:
* new(<i>name[,autosize]</i>)
* new(<i>name[,flags]</i>)
*
* Create new window named <i>name</i>.
* If <i>autoresize</i> is true(default), window size automatically resize when image given.
* If <i>flags</i> is CV_WINDOW_AUTOSIZE (default), window size automatically resize when image given.
*/
VALUE
rb_initialize(int argc, VALUE *argv, VALUE self)
{
VALUE name, autosize;
rb_scan_args(argc, argv, "11", &name, &autosize);
VALUE name, flags;
rb_scan_args(argc, argv, "11", &name, &flags);
Check_Type(name, T_STRING);
int mode;
if (argc < 2)
mode = CV_WINDOW_AUTOSIZE;
else{
switch (TYPE(autosize)) {
case T_TRUE:
mode = CV_WINDOW_AUTOSIZE;
break;
case T_FALSE:
mode = 0;
break;
default:
rb_raise(rb_eTypeError, "argument 2 (auto-size) should be true or false.");
}
int mode = CV_WINDOW_AUTOSIZE;
if (argc == 2) {
Check_Type(flags, T_FIXNUM);
mode = FIX2INT(flags);
}
cvNamedWindow(StringValueCStr(name), mode);
void *handle = cvGetWindowHandle(StringValueCStr(name));
char* name_str = StringValueCStr(name);
cvNamedWindow(name_str, mode);
void *handle = cvGetWindowHandle(name_str);
if (st_lookup(windows, (st_data_t)handle, 0)) {
rb_raise(rb_eStandardError, "window name should be unique.");
}
@ -217,7 +208,8 @@ rb_resize(int argc, VALUE *argv, VALUE self)
size = cvSize(FIX2INT(argv[0]), FIX2INT(argv[1]));
break;
default:
rb_raise(rb_eArgError, "wrong number of arguments (1 or 2)");
rb_raise(rb_eArgError, "wrong number of arguments (1 or 2)");
break;
}
cvResizeWindow(GET_WINDOW_NAME(self), size.width, size.height);
return self;
@ -242,7 +234,8 @@ rb_move(int argc, VALUE *argv, VALUE self)
point = cvPoint(FIX2INT(argv[0]), FIX2INT(argv[1]));
break;
default:
rb_raise(rb_eArgError, "wrong number of arguments (1 or 2)");
rb_raise(rb_eArgError, "wrong number of arguments (1 or 2)");
break;
}
cvMoveWindow(GET_WINDOW_NAME(self), point.x, point.y);
return self;
@ -252,22 +245,27 @@ rb_move(int argc, VALUE *argv, VALUE self)
* call-seq:
* show_image(<i>image</i>)
*
* Show the image. If the window was created with <i>autosize</i> = true then the image is shown
* Show the image. If the window was created with <i>flags</i> = CV_WINDOW_AUTOSIZE then the image is shown
* with its original size, otherwize the image is scaled to fit the window.
*/
VALUE
rb_show_image(VALUE self, VALUE image)
rb_show_image(int argc, VALUE *argv, VALUE self)
{
if (!rb_obj_is_kind_of(image, cCvMat::rb_class())) {
rb_raise(rb_eTypeError, "argument should be %s.", rb_class2name(cCvMat::rb_class()));
CvArr* image = NULL;
if (argc > 0) {
if (!rb_obj_is_kind_of(argv[0], cCvMat::rb_class()))
rb_raise(rb_eTypeError, "argument should be %s.", rb_class2name(cCvMat::rb_class()));
else
image = CVARR(argv[0]);
st_table *holder;
if (st_lookup(windows, (st_data_t)DATA_PTR(self), (st_data_t*)&holder)) {
st_insert(holder, cCvMat::rb_class(), argv[0]);
}else
rb_raise(rb_eFatal, "invalid window operation.");
}
cvShowImage(GET_WINDOW_NAME(self), CVARR(image));
st_table *holder;
if (st_lookup(windows, (st_data_t)DATA_PTR(self), (st_data_t*)&holder)) {
st_insert(holder, cCvMat::rb_class(), image);
return self;
}else
rb_raise(rb_eFatal, "invalid window operation.");
cvShowImage(GET_WINDOW_NAME(self), image);
return self;
}
@ -291,7 +289,8 @@ rb_set_trackbar(int argc, VALUE *argv, VALUE self)
}
Trackbar *trackbar = TRACKBAR(instance);
void *callback = (void *)alloc_callback(&trackbar_callback, trackbar->block);
cvCreateTrackbar(trackbar->name, GET_WINDOW_NAME(self), &trackbar->val, trackbar->maxval, (CvTrackbarCallback)callback);
cvCreateTrackbar(trackbar->name, GET_WINDOW_NAME(self), &(trackbar->val), trackbar->maxval,
(CvTrackbarCallback)callback);
st_table *holder;
if (st_lookup(windows, (st_data_t)DATA_PTR(self), (st_data_t*)&holder)) {
st_insert(holder, (st_data_t)&trackbar->name, (st_data_t)instance);
@ -326,10 +325,13 @@ rb_set_trackbar(int argc, VALUE *argv, VALUE self)
* OpenCV::GUI::wait_key
*/
VALUE
rb_set_mouse_callback(VALUE self)
{
VALUE block = rb_block_given_p() ? rb_block_proc() : 0;
if (!block) {rb_raise(rb_eArgError, "block not given.");}
rb_set_mouse_callback(int argc, VALUE* argv, VALUE self)
{
if (!rb_block_given_p())
rb_raise(rb_eArgError, "block not given.");
VALUE block = Qnil;
rb_scan_args(argc, argv, "0&", &block);
void *callback = (void *)alloc_callback(&mouse_callback, block);
cvSetMouseCallback(GET_WINDOW_NAME(self), (CvMouseCallback)callback);
st_table *holder;
@ -353,11 +355,11 @@ void
mouse_callback(VALUE block, va_alist ap)
{
va_start_void(ap);
//VALUE ary = rb_ary_new2(4);
//for (int i = 0; i < 4; i++)
// rb_ary_store(ary, i, INT2FIX(va_arg_int(ap)));
//rb_apply(block, rb_intern("call"), ary);
rb_funcall(block, rb_intern("call"), 1, cMouseEvent::new_object(va_arg_int(ap),va_arg_int(ap),va_arg_int(ap),va_arg_int(ap)));
int event = va_arg_int(ap);
int x = va_arg_int(ap);
int y = va_arg_int(ap);
int flags = va_arg_int(ap);
rb_funcall(block, rb_intern("call"), 1, cMouseEvent::new_object(event, x, y, flags));
va_return_void(ap);
}

View file

@ -40,9 +40,9 @@ VALUE rb_destroy(VALUE self);
VALUE rb_destroy_all(VALUE klass);
VALUE rb_resize(int argc, VALUE *argv, VALUE self);
VALUE rb_move(int argc, VALUE *argv, VALUE self);
VALUE rb_show_image(VALUE self, VALUE image);
VALUE rb_show_image(int argc, VALUE *argv, VALUE self);
VALUE rb_set_trackbar(int argc, VALUE *argv, VALUE self);
VALUE rb_set_mouse_callback(VALUE self);
VALUE rb_set_mouse_callback(int argc, VALUE* argv, VALUE self);
void trackbar_callback(VALUE block, va_alist ap);
void mouse_callback(VALUE block, va_alist ap);

View file

@ -72,7 +72,7 @@ else
end
# Quick fix for 1.8.7
$CFLAGS << "-I#{File.dirname(__FILE__)}/ext/opencv"
$CFLAGS << " -I#{File.dirname(__FILE__)}/ext/opencv"
# step-final. create Makefile
create_makefile("opencv", "./ext/opencv")

View file

@ -99,6 +99,9 @@ class TestOpenCV < OpenCVTestCase
assert_equal(2, CV_FM_8POINT)
assert_equal(8, CV_FM_RANSAC)
assert_equal(4, CV_FM_LMEDS)
# Flags of window
assert_equal(1, CV_WINDOW_AUTOSIZE)
end
def test_symbols

115
test/test_window.rb Executable file
View file

@ -0,0 +1,115 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
require 'test/unit'
require 'opencv'
require File.expand_path(File.dirname(__FILE__)) + '/helper'
include OpenCV
include GUI
# Tests for OpenCV::Window
class TestWindow < OpenCVTestCase
def setup
@window1 = Window.new('window1')
@window2 = Window.new('window2', CV_WINDOW_AUTOSIZE)
@window3 = Window.new('window3', 0)
end
def teardown
Window::destroy_all
end
def test_initialize
[Window.new('w1'), Window.new('w2', CV_WINDOW_AUTOSIZE), Window.new('w3', 0)].each { |w|
assert_not_nil(w)
assert_equal(Window, w.class)
}
assert_raise(TypeError) {
Window.new('w4', 'foobar')
}
assert_raise(StandardError) {
Window.new('w5')
Window.new('w5')
}
end
def test_alive
assert(@window1.alive?)
@window1.destroy
assert(!(@window1.alive?))
end
def test_destroy
@window1.destroy
assert(!(@window1.alive?))
end
def test_destroy_all
Window::destroy_all
assert(!(@window1.alive?))
assert(!(@window2.alive?))
assert(!(@window3.alive?))
end
def test_resize
@window1.resize(CvSize.new(10, 20))
@window2.resize(100, 200)
assert_raise(ArgumentError) {
@window3.resize
}
# Uncomment the following lines to show the results
# @window1.show(CvMat.new(10, 20))
# @window2.show(CvMat.new(100, 200))
# GUI::wait_key
end
def test_move
@window1.move(CvPoint.new(10, 20))
@window2.move(100, 200)
assert_raise(ArgumentError) {
@window3.move
}
# Uncomment the following lines to show the results
# @window1.show(CvMat.new(10, 20))
# @window2.show(CvMat.new(100, 200))
# GUI::wait_key
end
def test_show_image
img = IplImage.load(FILENAME_CAT, CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR)
@window1.show_image(img)
@window2.show # Alias
# Uncomment the following lines to show the results
# GUI::wait_key
end
def test_set_trackbar
tr1 = @window1.set_trackbar('trackbar1', 100) { |value|
puts value
}
assert_equal(Trackbar, tr1.class)
trackbar2 = Trackbar.new('trackbar2', 10, 1) {}
tr2 = @window2.set_trackbar(trackbar2)
assert_equal(Trackbar, tr2.class)
end
def test_set_mouseevent
@window1.set_mouse_callback { |mouse|
e = "#{mouse.x}, #{mouse.y} : #{mouse.event} : "
e << "<L>" if mouse.left_button?
e << "<R>" if mouse.right_button?
e << "<M>" if mouse.middle_button?
e << "[CTRL]" if mouse.ctrl_key?
e << "[SHIFT]" if mouse.shift_key?
e << "[ALT]" if mouse.alt_key?
puts e
}
end
end