Sublet class for interaction with sublets
Methods
Public Instance
Public Instance methods
config -> Hash
Get config hash from config
s.config => { :interval => 30 }
[show source]
static VALUE RubySubletConfig(VALUE self) { SubPanel *p = NULL; VALUE hash = Qnil; Data_Get_Struct(self, SubPanel, p); if(p) { /* Get config hash */ if(NIL_P(hash = rb_hash_lookup(config_sublets, CHAR2SYM(p->sublet->name)))) hash = rb_hash_new(); } return hash; }
configure -> nil
Configure block for Sublet
configure :sublet do |s| s.interval = 60 end
[show source]
static VALUE RubySubletConfigure(VALUE self, VALUE name) { rb_need_block(); /* Check value type */ if(T_SYMBOL == rb_type(name)) { SubPanel *p = NULL; Data_Get_Struct(self, SubPanel, p); if(p) { VALUE proc = Qnil; /* Assume latest sublet */ proc = rb_block_proc(); p->sublet->name = strdup(SYM2CHAR(name)); /* Define configure method */ rb_funcall(rb_singleton_class(p->sublet->instance), rb_intern("define_method"), 2, CHAR2SYM("__configure"), proc); } } else rb_raise(rb_eArgError, "Unknown value type for configure"); return Qnil; }
data -> String or nil
Get data of Sublet
puts sublet.data => "subtle"
[show source]
static VALUE RubySubletDataReader(VALUE self) { int i; VALUE string = Qnil; SubPanel *p = NULL; Data_Get_Struct(self, SubPanel, p); if(p) { if(0 < p->sublet->text->nitems) { /* Concat string */ for(i = 0; i < p->sublet->text->nitems; i++) { SubTextItem *item = (SubTextItem *)p->sublet->text->items[i]; if(Qnil == string) rb_str_new2(item->data.string); else rb_str_cat(string, item->data.string, strlen(item->data.string)); } } } return string; }
data=(string) -> nil
Set data of Sublet
sublet.data = "subtle" => nil
[show source]
static VALUE RubySubletDataWriter(VALUE self, VALUE value) { SubPanel *p = NULL; Data_Get_Struct(self, SubPanel, p); if(p) { /* Check value type */ if(T_STRING == rb_type(value)) { SubStyle *s = &subtle->styles.sublets, *style = NULL; /* Select style */ if(s->styles && (style = subArrayGet(s->styles, p->sublet->styleid))) s = style; p->sublet->width = subTextParse(p->sublet->text, subtle->styles.sublets.font, RSTRING_PTR(value)) + STYLE_WIDTH((*s)); } else rb_raise(rb_eArgError, "Unknown value type"); } return Qnil; }
geometry -> Subtlext::Geometry
Get geometry of a sublet
sublet.geometry => #<Subtlext::Geometry:xxx>
[show source]
VALUE RubySubletGeometryReader(VALUE self) { SubPanel *p = NULL; VALUE geometry = Qnil; Data_Get_Struct(self, SubPanel, p); if(p) { SubStyle *s = NULL; XRectangle geom = { 0 }; VALUE subtlext = Qnil, klass = Qnil; /* Pick sublet style */ if(subtle->styles.sublets.styles) s = subArrayGet(subtle->styles.sublets.styles, p->sublet->styleid); subPanelGeometry(p, s ? s : &subtle->styles.sublets, &geom); /* Create geometry object */ subtlext = rb_const_get(rb_mKernel, rb_intern("Subtlext")); klass = rb_const_get(subtlext, rb_intern("Geometry")); geometry = rb_funcall(klass, rb_intern("new"), 4, INT2FIX(geom.x), INT2FIX(geom.y), INT2FIX(geom.width), INT2FIX(geom.height)); } return geometry; }
grab(chain, &block) -> nil
Add grabs to sublets
grab "A-b" do |s| puts s.name end
[show source]
static VALUE RubySubletGrab(VALUE self, VALUE name) { /* Check value type */ if(T_SYMBOL == rb_type(name) && rb_block_given_p()) { SubPanel *p = NULL; Data_Get_Struct(self, SubPanel, p); if(p) { int i; char buf[64] = { 0 }; VALUE meth = Qnil; /* Add proc as instance method */ snprintf(buf, sizeof(buf), "__grab_%s", SYM2CHAR(name)); rb_funcall(rb_singleton_class(p->sublet->instance), rb_intern("define_method"), 2, CHAR2SYM(buf), rb_block_proc()); meth = rb_obj_method(p->sublet->instance, CHAR2SYM(buf)); /* Find grabs with this symbol */ for(i = 0; i < subtle->grabs->ndata; i++) { SubGrab *g = GRAB(subtle->grabs->data[i]); if(g->flags & SUB_RUBY_DATA && g->data.num == name) { g->flags ^= (SUB_RUBY_DATA|SUB_GRAB_PROC); g->data.num = (unsigned long)meth; rb_ary_push(shelter, meth); ///< Protect from GC } } } } else rb_raise(rb_eArgError, "Unknown value type for grab"); return Qnil; }
helper -> nil
Helper block for Sublet
helper do |s| def test puts "test" end end
[show source]
static VALUE RubySubletHelper(VALUE self) { SubPanel *p = NULL; rb_need_block(); Data_Get_Struct(self, SubPanel, p); if(p) { /* Instance eval the block */ rb_yield_values(1, p->sublet->instance); rb_obj_instance_eval(0, 0, p->sublet->instance); } return Qnil; }
hide -> nil
Hide sublet from panel
sublet.hide => nil
[show source]
static VALUE RubySubletHide(VALUE self, VALUE value) { SubPanel *p = NULL; Data_Get_Struct(self, SubPanel, p); if(p) { p->flags |= SUB_PANEL_HIDDEN; /* Update screens */ subScreenUpdate(); subScreenRender(); } return Qnil; }
interval -> Fixnum
Get interval time of Sublet
puts sublet.interval => 60
[show source]
static VALUE RubySubletIntervalReader(VALUE self) { SubPanel *p = NULL; Data_Get_Struct(self, SubPanel, p); return p ? INT2FIX(p->sublet->interval) : Qnil; }
interval=(fixnum) -> nil
Set interval time of Sublet
sublet.interval = 60 => nil
[show source]
static VALUE RubySubletIntervalWriter(VALUE self, VALUE value) { SubPanel *p = NULL; Data_Get_Struct(self, SubPanel, p); if(p) { if(FIXNUM_P(value)) { p->sublet->interval = FIX2INT(value); p->sublet->time = subSubtleTime() + p->sublet->interval; if(0 < p->sublet->interval) p->sublet->flags |= SUB_SUBLET_INTERVAL; else p->sublet->flags &= ~SUB_SUBLET_INTERVAL; } else rb_raise(rb_eArgError, "Unknown value type `%s'", rb_obj_classname(value)); } return Qnil; }
name -> String
Get name of Sublet
puts sublet.name => "sublet"
[show source]
static VALUE RubySubletNameReader(VALUE self) { SubPanel *p = NULL; Data_Get_Struct(self, SubPanel, p); return p ? rb_str_new2(p->sublet->name) : Qnil; }
on(event, &block) -> nil
Event block for hooks
on :event do |s| puts s.name end
[show source]
static VALUE RubySubletOn(VALUE self, VALUE event) { /* Check value type */ if(T_SYMBOL == rb_type(event) && rb_block_given_p()) { SubPanel *p = NULL; Data_Get_Struct(self, SubPanel, p); if(p) { char buf[64] = { 0 }; int i, arity = 0; VALUE proc = Qnil, sing = Qnil, meth = Qnil; RubyMethods methods[] = { { CHAR2SYM("run"), CHAR2SYM("__run"), SUB_SUBLET_RUN, 1 }, { CHAR2SYM("data"), CHAR2SYM("__data"), SUB_SUBLET_DATA, 2 }, { CHAR2SYM("watch"), CHAR2SYM("__watch"), SUB_SUBLET_WATCH, 1 }, { CHAR2SYM("unload"), CHAR2SYM("__unload"), SUB_SUBLET_UNLOAD, 1 }, { CHAR2SYM("mouse_down"), CHAR2SYM("__down"), SUB_PANEL_DOWN, 4 }, { CHAR2SYM("mouse_over"), CHAR2SYM("__over"), SUB_PANEL_OVER, 1 }, { CHAR2SYM("mouse_out"), CHAR2SYM("__out"), SUB_PANEL_OUT, 1 } }; /* Collect stuff */ proc = rb_block_proc(); arity = rb_proc_arity(proc); sing = rb_singleton_class(p->sublet->instance); meth = rb_intern("define_method"); /* Special hooks */ for(i = 0; LENGTH(methods) > i; i++) { if(methods[i].sym == event) { /* Check proc arity */ if(-1 == arity || (1 <= arity && methods[i].arity >= arity)) { /* Add flags */ if(methods[i].flags & (SUB_PANEL_DOWN| SUB_PANEL_OVER|SUB_PANEL_OUT)) p->flags |= methods[i].flags; else p->sublet->flags |= methods[i].flags; /* Create instance method from proc */ rb_funcall(sing, meth, 2, methods[i].real, proc); return Qnil; } else rb_raise(rb_eArgError, "Wrong number of arguments (%d for %d)", arity, methods[i].arity); } } /* Generic hooks */ snprintf(buf, sizeof(buf), "__hook_%s", SYM2CHAR(event)); rb_funcall(sing, meth, 2, CHAR2SYM(buf), proc); RubyEvalHook(event, rb_obj_method(p->sublet->instance, CHAR2SYM(buf))); } } else rb_raise(rb_eArgError, "Unknown value type for on"); return Qnil; }
render -> nil
Render a Sublet
sublet.render => nil
[show source]
static VALUE RubySubletRender(VALUE self) { SubPanel *p = NULL; Data_Get_Struct(self, SubPanel, p); if(p) subScreenRender(); return Qnil; }
screen -> Subtlext::Screen
Get screen of a sublet
sublet.screen => #<Subtlext::screen:xxx>
[show source]
VALUE RubySubletScreenReader(VALUE self) { SubPanel *p = NULL; VALUE screen = Qnil; Data_Get_Struct(self, SubPanel, p); if(p) screen = RubySubtleToSubtlext(p->screen); return screen; }
show -> nil
Show sublet on panel
sublet.show => nil
[show source]
static VALUE RubySubletShow(VALUE self) { SubPanel *p = NULL; Data_Get_Struct(self, SubPanel, p); if(p) { p->flags &= ~SUB_PANEL_HIDDEN; /* Update screens */ subScreenUpdate(); subScreenRender(); } return Qnil; }
style=(string) -> nil
style=(symbol) -> nil
Set style of Sublet
sublet.style = :subtle => nil
[show source]
static VALUE RubySubletStyleWriter(VALUE self, VALUE value) { SubPanel *p = NULL; Data_Get_Struct(self, SubPanel, p); if(p) { /* Check value type */ if(FIXNUM_P(value)) { SubStyle *s = &subtle->styles.sublets, *style = NULL; /* Select style */ if(s->styles && (style = subArrayGet(s->styles, FIX2INT(value)))) { s = style; p->sublet->styleid = FIX2INT(value); } p->sublet->width = subTextParse(p->sublet->text, subtle->styles.sublets.font, RSTRING_PTR(value)) + STYLE_WIDTH((*s)); } else rb_raise(rb_eArgError, "Unknown value type"); } return Qnil; }
unwatch -> true or false
Remove watch from Sublet
unwatch => true
[show source]
static VALUE RubySubletUnwatch(VALUE self) { VALUE ret = Qfalse; SubPanel *p = NULL; Data_Get_Struct(self, SubPanel, p); if(p) { /* Probably a socket */ if(p->sublet->flags & SUB_SUBLET_SOCKET) { XDeleteContext(subtle->dpy, subtle->windows.support, p->sublet->watch); subEventWatchDel(p->sublet->watch); p->sublet->flags &= ~SUB_SUBLET_SOCKET; p->sublet->watch = 0; ret = Qtrue; } #ifdef HAVE_SYS_INOTIFY_H /* Inotify file */ else if(p->sublet->flags & SUB_SUBLET_INOTIFY) { subSubtleLogDebug("Inotify: remove watch=%d\n", p->sublet->watch); XDeleteContext(subtle->dpy, subtle->windows.support, p->sublet->watch); inotify_rm_watch(subtle->notify, p->sublet->watch); p->sublet->flags &= ~SUB_SUBLET_INOTIFY; p->sublet->watch = 0; ret = Qtrue; } #endif /* HAVE_SYS_INOTIFY_H */ } return ret; }
warn(string) -> nil
Print sublet warning
sublet.warn("test") => "<WARNING SUBLET sublet> test"
[show source]
static VALUE RubySubletWarn(VALUE self, VALUE str) { SubPanel *p = NULL; Data_Get_Struct(self, SubPanel, p); if(p && T_STRING == rb_type(str)) subSubtleLogSubletError(p->sublet->name, RSTRING_PTR(str)); return Qnil; }
watch(source) -> true or false
Add watch file via inotify or socket
watch "/path/to/file" => true @socket = TCPSocket("localhost", 6600) watch @socket
[show source]
static VALUE RubySubletWatch(VALUE self, VALUE value) { VALUE ret = Qfalse; SubPanel *p = NULL; Data_Get_Struct(self, SubPanel, p); if(p) { if(!(p->sublet->flags & (SUB_SUBLET_SOCKET|SUB_SUBLET_INOTIFY)) && RTEST(value)) { /* Socket file descriptor or ruby socket */ if(FIXNUM_P(value) || rb_respond_to(value, rb_intern("fileno"))) { int flags = 0; p->sublet->flags |= SUB_SUBLET_SOCKET; /* Get socket file descriptor */ if(FIXNUM_P(value)) p->sublet->watch = FIX2INT(value); else { p->sublet->watch = FIX2INT(rb_funcall(value, rb_intern("fileno"), 0, NULL)); } XSaveContext(subtle->dpy, subtle->windows.support, p->sublet->watch, (void *)p); subEventWatchAdd(p->sublet->watch); /* Set nonblocking */ if(-1 == (flags = fcntl(p->sublet->watch, F_GETFL, 0))) flags = 0; fcntl(p->sublet->watch, F_SETFL, flags | O_NONBLOCK); ret = Qtrue; } #ifdef HAVE_SYS_INOTIFY_H else if(T_STRING == rb_type(value)) /// Inotify file { char buf[100] = { 0 }; #ifdef HAVE_WORDEXP_H /* Expand tildes in path */ wordexp_t we; if(0 == wordexp(RSTRING_PTR(value), &we, 0)) { snprintf(buf, sizeof(buf), "%s", we.we_wordv[0]); wordfree(&we); } else #endif /* HAVE_WORDEXP_H */ snprintf(buf, sizeof(buf), "%s", RSTRING_PTR(value)); /* Create inotify watch */ if(0 < (p->sublet->watch = inotify_add_watch( subtle->notify, buf, IN_MODIFY))) { p->sublet->flags |= SUB_SUBLET_INOTIFY; XSaveContext(subtle->dpy, subtle->windows.support, p->sublet->watch, (void *)p); subSubtleLogDebug("Inotify: add watch=%s\n", buf); ret = Qtrue; } else subSubtleLogWarn("Cannot watch file `%s': %s\n", buf, strerror(errno)); } #endif /* HAVE_SYS_INOTIFY_H */ else rb_raise(rb_eArgError, "Unexpected value-type `%s'", rb_obj_classname(value)); } } return ret; }