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;
}