Skip to content

Commit

Permalink
n #270 add the methods_new.h file - should have been in previous commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Cecil committed Mar 31, 2019
1 parent 37adfae commit aa4d2e7
Showing 1 changed file with 398 additions and 0 deletions.
398 changes: 398 additions & 0 deletions shoes/methods_new.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,398 @@
#ifndef SHOES_METHODS_M_H
#define SHOES_METHODS_M_H

/* Deprecated Extension API TODO: Find these (canvas.*?) and replace
* #define GET_STRUCT(ele, var) \
* shoes_##ele *var; \
* Data_Get_Struct(self, shoes_##ele, var)
*
* To really make sure the old api is not being used, remove it
*/
#ifdef Data_Get_Struct
#undef Data_Get_Struct
#endif

/*
* New Extension API
*/
// creates the rb_data_type_t part of underlaying C foundation of a becoming ruby object
#define TypedData_Type_New(wrapped) \
const rb_data_type_t wrapped##_type = { \
#wrapped "_type", \
{ \
(void (*)(void *))wrapped##_mark, \
(void (*)(void *))wrapped##_free, \
(size_t (*)(const void *))sizeof(wrapped), \
}, \
0, 0, \
RUBY_TYPED_FREE_IMMEDIATELY, \
}

// unwraps a ruby object (implicit self), declare var of type wrapped
#define Get_TypedStruct(wrapped, var) \
wrapped *var; \
TypedData_Get_Struct(self, wrapped, &wrapped##_type, var)

// unwraps a ruby object (rbObject), declare var of type wrapped
#define Get_TypedStruct2(rbObject, wrapped, var) \
wrapped *var; \
TypedData_Get_Struct(rbObject, wrapped, &wrapped##_type, var)

// unwraps a ruby object (rbObject), "returns" the wrapped struct
#define Get_TypedStruct3(rbObject, wrapped) \
(wrapped*)rb_check_typeddata((rbObject), (&wrapped##_type))


//
// Defines a redirecting function which applies the element or transformation
// to the currently active canvas. This is used in place of the old instance_eval
// and ensures that you have access to the App's instance variables while
// assembling elements in a layout.
//
//
#define FUNC_T(name, func, argn) \
VALUE \
shoes_canvas_c_##func(int argc, VALUE *argv, VALUE self) \
{ \
VALUE canvas, obj; \
shoes_canvas *self_t; \
TypedData_Get_Struct(self, shoes_canvas, &shoes_canvas_type, self_t); \
char *n = name; \
if (rb_ary_entry(self_t->app->nesting, 0) == self || \
((rb_obj_is_kind_of(self, cWidget) || self == self_t->app->nestslot) && \
RARRAY_LEN(self_t->app->nesting) > 0)) \
canvas = rb_ary_entry(self_t->app->nesting, RARRAY_LEN(self_t->app->nesting) - 1); \
else \
canvas = self; \
if (!rb_obj_is_kind_of(canvas, cCanvas)) \
return ts_funcall2(canvas, rb_intern(n + 1), argc, argv); \
obj = call_cfunc(CASTHOOK(shoes_canvas_##func), canvas, argn, argc, argv); \
if (n[0] == '+' && RARRAY_LEN(self_t->app->nesting) == 0) shoes_canvas_repaint_all(self); \
return obj; \
} \
VALUE \
shoes_app_c_##func(int argc, VALUE *argv, VALUE self) \
{ \
VALUE canvas; \
char *n = name; \
shoes_app *app; \
TypedData_Get_Struct(self, shoes_app, &shoes_app_type, app); \
if (RARRAY_LEN(app->nesting) > 0) \
canvas = rb_ary_entry(app->nesting, RARRAY_LEN(app->nesting) - 1); \
else \
canvas = app->canvas; \
if (!rb_obj_is_kind_of(canvas, cCanvas)) \
return ts_funcall2(canvas, rb_intern(n + 1), argc, argv); \
return shoes_canvas_c_##func(argc, argv, canvas); \
}


//
// Transformations
//
#define TRANS_COMMON(ele, repaint) \
VALUE \
shoes_##ele##_transform(VALUE self, VALUE _m) \
{ \
shoes_##ele *self_t; \
TypedData_Get_Struct(self, shoes_##ele, &shoes_##ele##_type, self_t); \
ID m = SYM2ID(_m); \
if (m == s_center || m == s_corner) \
{ \
self_t->st = shoes_transform_detach(self_t->st); \
self_t->st->mode = m; \
} \
else \
{ \
rb_raise(rb_eArgError, "transform must be called with either :center or :corner."); \
} \
return self; \
} \
VALUE \
shoes_##ele##_translate(VALUE self, VALUE _x, VALUE _y) \
{ \
shoes_##ele *self_t; \
TypedData_Get_Struct(self, shoes_##ele, &shoes_##ele##_type, self_t); \
double x, y; \
x = NUM2DBL(_x); \
y = NUM2DBL(_y); \
self_t->st = shoes_transform_detach(self_t->st); \
cairo_matrix_translate(&self_t->st->tf, x, y); \
return self; \
} \
VALUE \
shoes_##ele##_rotate(VALUE self, VALUE _deg) \
{ \
shoes_##ele *self_t; \
TypedData_Get_Struct(self, shoes_##ele, &shoes_##ele##_type, self_t); \
double rad; \
rad = NUM2DBL(_deg) * SHOES_RAD2PI; \
self_t->st = shoes_transform_detach(self_t->st); \
cairo_matrix_rotate(&self_t->st->tf, -rad); \
if (repaint) shoes_canvas_repaint_all(self_t->parent); \
return self; \
} \
VALUE \
shoes_##ele##_scale(int argc, VALUE *argv, VALUE self) \
{ \
shoes_##ele *self_t; \
TypedData_Get_Struct(self, shoes_##ele, &shoes_##ele##_type, self_t); \
VALUE _sx, _sy; \
double sx, sy; \
rb_scan_args(argc, argv, "11", &_sx, &_sy); \
sx = NUM2DBL(_sx); \
if (NIL_P(_sy)) sy = sx; \
else sy = NUM2DBL(_sy); \
self_t->st = shoes_transform_detach(self_t->st); \
cairo_matrix_scale(&self_t->st->tf, sx, sy); \
if (repaint) shoes_canvas_repaint_all(self_t->parent); \
return self; \
} \
VALUE \
shoes_##ele##_skew(int argc, VALUE *argv, VALUE self) \
{ \
shoes_##ele *self_t; \
TypedData_Get_Struct(self, shoes_##ele, &shoes_##ele##_type, self_t); \
cairo_matrix_t matrix; \
VALUE _sx, _sy; \
double sx, sy; \
rb_scan_args(argc, argv, "11", &_sx, &_sy); \
sx = NUM2DBL(_sx) * SHOES_RAD2PI; \
sy = 0.0; \
if (!NIL_P(_sy)) sy = NUM2DBL(_sy) * SHOES_RAD2PI; \
cairo_matrix_init(&matrix, 1.0, sy, sx, 1.0, 0.0, 0.0); \
self_t->st = shoes_transform_detach(self_t->st); \
cairo_matrix_multiply(&self_t->st->tf, &self_t->st->tf, &matrix); \
if (repaint) shoes_canvas_repaint_all(self_t->parent); \
return self; \
}

#define REPLACE_COMMON_T(ele) \
VALUE \
shoes_##ele##_replace(int argc, VALUE *argv, VALUE self) \
{ \
shoes_##ele *self_t; \
TypedData_Get_Struct(self, shoes_##ele, &shoes_##ele##_type, self_t); \
long i; \
shoes_textblock *block_t; \
VALUE texts, attr, block; \
attr = Qnil; \
texts = rb_ary_new(); \
for (i = 0; i < argc; i++) \
{ \
if (rb_obj_is_kind_of(argv[i], rb_cHash)) \
attr = argv[i]; \
else \
rb_ary_push(texts, argv[i]); \
} \
self_t->texts = texts; \
if (!NIL_P(attr)) self_t->attr = attr; \
block = shoes_find_textblock(self); \
TypedData_Get_Struct(block, shoes_textblock, &shoes_textblock_type, block_t); \
shoes_textblock_uncache(block_t, TRUE); \
shoes_canvas_repaint_all(self_t->parent); \
return self; \
}

//
// Common methods
//
#define EVENT_COMMON(ele, est, sym) \
VALUE \
shoes_##ele##_##sym(int argc, VALUE *argv, VALUE self) \
{ \
shoes_##est *self_t; \
TypedData_Get_Struct(self, shoes_##est, &shoes_##est##_type, self_t); \
VALUE str = Qnil, blk = Qnil; \
\
rb_scan_args(argc, argv, "01&", &str, &blk); \
if (NIL_P(self_t->attr)) self_t->attr = rb_hash_new(); \
rb_hash_aset(self_t->attr, ID2SYM(s_##sym), NIL_P(blk) ? str : blk ); \
return self; \
}

#define CLASS_COMMON(ele) \
VALUE \
shoes_##ele##_style(int argc, VALUE *argv, VALUE self) \
{ \
shoes_##ele *self_t; \
TypedData_Get_Struct(self, shoes_##ele, &shoes_##ele##_type, self_t); \
rb_arg_list args; \
switch (rb_parse_args(argc, argv, "h,", &args)) { \
case 1: \
if (NIL_P(self_t->attr)) self_t->attr = rb_hash_new(); \
rb_funcall(self_t->attr, s_update, 1, args.a[0]); \
shoes_canvas_repaint_all(self_t->parent); \
break; \
case 2: return rb_obj_freeze(rb_obj_dup(self_t->attr)); \
} \
return self; \
} \
\
VALUE \
shoes_##ele##_displace(VALUE self, VALUE x, VALUE y) \
{ \
shoes_##ele *self_t; \
TypedData_Get_Struct(self, shoes_##ele, &shoes_##ele##_type, self_t); \
ATTRSET(self_t->attr, displace_left, x); \
ATTRSET(self_t->attr, displace_top, y); \
shoes_canvas_repaint_all(self_t->parent); \
return self; \
} \
\
VALUE \
shoes_##ele##_move(VALUE self, VALUE x, VALUE y) \
{ \
shoes_##ele *self_t; \
TypedData_Get_Struct(self, shoes_##ele, &shoes_##ele##_type, self_t); \
ATTRSET(self_t->attr, left, x); \
ATTRSET(self_t->attr, top, y); \
shoes_canvas_repaint_all(self_t->parent); \
return self; \
}

#define CLASS_COMMON2(ele) \
VALUE \
shoes_##ele##_hide(VALUE self) \
{ \
shoes_##ele *self_t; \
TypedData_Get_Struct(self, shoes_##ele, &shoes_##ele##_type, self_t); \
ATTRSET(self_t->attr, hidden, Qtrue); \
shoes_canvas_repaint_all(self_t->parent); \
return self; \
} \
\
VALUE \
shoes_##ele##_show(VALUE self) \
{ \
shoes_##ele *self_t; \
TypedData_Get_Struct(self, shoes_##ele, &shoes_##ele##_type, self_t); \
ATTRSET(self_t->attr, hidden, Qfalse); \
shoes_canvas_repaint_all(self_t->parent); \
return self; \
} \
\
VALUE \
shoes_##ele##_toggle(VALUE self) \
{ \
shoes_##ele *self_t; \
TypedData_Get_Struct(self, shoes_##ele, &shoes_##ele##_type, self_t); \
ATTRSET(self_t->attr, hidden, ATTR(self_t->attr, hidden) == Qtrue ? Qfalse : Qtrue); \
shoes_canvas_repaint_all(self_t->parent); \
return self; \
} \
\
VALUE \
shoes_##ele##_is_hidden(VALUE self) \
{ \
shoes_##ele *self_t; \
TypedData_Get_Struct(self, shoes_##ele, &shoes_##ele##_type, self_t); \
if (RTEST(ATTR(self_t->attr, hidden))) \
return ATTR(self_t->attr, hidden); \
else return Qfalse; \
} \
CLASS_COMMON(ele); \
EVENT_COMMON(ele, ele, change); \
EVENT_COMMON(ele, ele, click); \
EVENT_COMMON(ele, ele, release); \
EVENT_COMMON(ele, ele, hover); \
EVENT_COMMON(ele, ele, leave);

#define PLACE_COMMON(ele) \
VALUE \
shoes_##ele##_get_parent(VALUE self) \
{ \
shoes_##ele *self_t; \
TypedData_Get_Struct(self, shoes_##ele, &shoes_##ele##_type, self_t); \
return self_t->parent; \
} \
\
VALUE \
shoes_##ele##_get_left(VALUE self) \
{ \
shoes_##ele *self_t; \
TypedData_Get_Struct(self, shoes_##ele, &shoes_##ele##_type, self_t); \
shoes_canvas *canvas = NULL; \
if (!NIL_P(self_t->parent)) { \
TypedData_Get_Struct(self_t->parent, shoes_canvas, &shoes_canvas_type, canvas); \
} else { \
TypedData_Get_Struct(self, shoes_canvas, &shoes_canvas_type, canvas); \
} \
return INT2NUM(self_t->place.x - CPX(canvas)); \
} \
\
VALUE \
shoes_##ele##_get_top(VALUE self) \
{ \
shoes_##ele *self_t; \
TypedData_Get_Struct(self, shoes_##ele, &shoes_##ele##_type, self_t); \
shoes_canvas *canvas = NULL; \
if (!NIL_P(self_t->parent)) { \
TypedData_Get_Struct(self_t->parent, shoes_canvas, RTYPEDDATA_TYPE(self_t->parent), canvas); \
} else { \
TypedData_Get_Struct(self, shoes_canvas, RTYPEDDATA_TYPE(self), canvas); \
} \
return INT2NUM(self_t->place.y - CPY(canvas)); \
} \
\
VALUE \
shoes_##ele##_get_height(VALUE self) \
{ \
shoes_##ele *self_t; \
TypedData_Get_Struct(self, shoes_##ele, &shoes_##ele##_type, self_t); \
return INT2NUM(self_t->place.h); \
} \
\
VALUE \
shoes_##ele##_get_width(VALUE self) \
{ \
shoes_##ele *self_t; \
TypedData_Get_Struct(self, shoes_##ele, &shoes_##ele##_type, self_t); \
return INT2NUM(self_t->place.w); \
}

//
// Macros for setting up drawing
//
#define SETUP_DRAWING_T(self_type, rel, dw, dh) \
self_type *self_t; \
shoes_place place; \
shoes_canvas *canvas; \
TypedData_Get_Struct(self, self_type, &self_type##_type, self_t); \
TypedData_Get_Struct(c, shoes_canvas, &shoes_canvas_type, canvas); \
if (ATTR(self_t->attr, hidden) == Qtrue) return self; \
shoes_place_decide(&place, c, self_t->attr, dw, dh, rel, REL_COORDS(rel) == REL_CANVAS)

#define SETUP_CANVAS() \
shoes_canvas *canvas; \
cairo_t *cr; \
TypedData_Get_Struct(self, shoes_canvas, &shoes_canvas_type, canvas); \
cr = CCR(canvas)

#define SETUP_IMAGE() \
shoes_place place; \
shoes_image *image; \
TypedData_Get_Struct(self, shoes_image, &shoes_image_type, image); \
shoes_image_ensure_dup(image); \
shoes_place_exact(&place, attr, 0, 0); \
if (NIL_P(attr)) attr = image->attr; \
else if (!NIL_P(image->attr)) attr = rb_funcall(image->attr, s_merge, 1, attr);

#define SETUP_CONTROL_T(dh, dw, flex) \
char *msg = ""; \
int len = dw ? dw : 200; \
shoes_control *self_t; \
shoes_canvas *canvas; \
shoes_place place; \
VALUE text = Qnil, ck = rb_obj_class(c); \
TypedData_Get_Struct(self, shoes_control, &shoes_control_type, self_t); \
TypedData_Get_Struct(c, shoes_canvas, &shoes_canvas_type, canvas); \
text = ATTR(self_t->attr, text); \
if (!NIL_P(text)) { \
text = shoes_native_to_s(text); \
msg = RSTRING_PTR(text); \
if (flex) len = ((int)RSTRING_LEN(text) * 8) + 32; \
} \
shoes_place_decide(&place, c, self_t->attr, len, 28 + dh, REL_CANVAS, TRUE)

#endif

0 comments on commit aa4d2e7

Please sign in to comment.