--- deliantra/Deliantra-Client/Client.xs 2007/07/21 16:07:53 1.208 +++ deliantra/Deliantra-Client/Client.xs 2007/07/21 22:54:52 1.209 @@ -437,6 +437,9 @@ /******************************************************************************/ +static GV *draw_x_gv, *draw_y_gv, *draw_w_gv, *draw_h_gv; +static GV *hover_gv; + static int within_widget (SV *widget, NV x, NV y) { @@ -2628,10 +2631,109 @@ PROTOTYPES: DISABLE void -find_widget (SV *widget, NV x, NV y) +find_widget (SV *self, NV x, NV y) PPCODE: { - if (within_widget (widget, x, y)) - XPUSHs (widget); + if (within_widget (self, x, y)) + XPUSHs (self); +} + +BOOT: +{ + hover_gv = gv_fetchpv ("CFPlus::UI::HOVER", 1, SVt_NV); + + draw_x_gv = gv_fetchpv ("CFPlus::UI::Base::draw_x", 1, SVt_NV); + draw_y_gv = gv_fetchpv ("CFPlus::UI::Base::draw_y", 1, SVt_NV); + draw_w_gv = gv_fetchpv ("CFPlus::UI::Base::draw_w", 1, SVt_NV); + draw_h_gv = gv_fetchpv ("CFPlus::UI::Base::draw_h", 1, SVt_NV); +} + +void +draw (SV *self) + CODE: +{ + HV *hv; + SV **svp; + NV x, y, w, h; + SV *draw_x_sv = GvSV (draw_x_gv); + SV *draw_y_sv = GvSV (draw_y_gv); + SV *draw_w_sv = GvSV (draw_w_gv); + SV *draw_h_sv = GvSV (draw_h_gv); + SV *hover; + double draw_x, draw_y, draw_w, draw_h; + + if (!SvROK (self)) + croak ("CFPlus::Base::draw: %s not a reference", SvPV_nolen (self)); + + hv = (HV *)SvRV (self); + + if (SvTYPE (hv) != SVt_PVHV) + croak ("CFPlus::Base::draw: %s not a hashref", SvPV_nolen (self)); + + svp = hv_fetch (hv, "w", 1, 0); w = svp ? SvNV (*svp) : 0.; + svp = hv_fetch (hv, "h", 1, 0); h = svp ? SvNV (*svp) : 0.; + + if (!h || !w) + XSRETURN_EMPTY; + + svp = hv_fetch (hv, "x", 1, 0); x = svp ? SvNV (*svp) : 0.; + svp = hv_fetch (hv, "y", 1, 0); y = svp ? SvNV (*svp) : 0.; + + draw_x = SvNV (draw_x_sv) + x; + draw_y = SvNV (draw_y_sv) + y; + + if (draw_x + w < 0 || draw_x >= SvNV (draw_w_sv) + || draw_y + h < 0 || draw_y >= SvNV (draw_h_sv)) + XSRETURN_EMPTY; + + sv_setnv (draw_x_sv, draw_x); + sv_setnv (draw_y_sv, draw_y); + + glPushMatrix (); + glTranslated (x, y, 0); + + if (SvROK (GvSV (hover_gv)) && SvRV (GvSV (hover_gv)) == (SV *)hv) + { + svp = hv_fetch (hv, "can_hover", sizeof ("can_hover") - 1, 0); + + if (svp && SvTRUE (*svp)) + { + glColor4f (1*0.2f, 0.8*0.2f, 0.5*0.2f, 0.2f); + glEnable (GL_BLEND); + glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + glBegin (GL_QUADS); + glVertex2f (0, 0); + glVertex2f (w, 0); + glVertex2f (w, h); + glVertex2f (0, h); + glEnd (); + glDisable (GL_BLEND); + } + } +#if 0 + if ($ENV{CFPLUS_DEBUG} & 1) { + glPushMatrix; + glColor 1, 1, 0, 1; + glTranslate 0.375, 0.375; + glBegin GL_LINE_LOOP; + glVertex 0 , 0; + glVertex $self->{w} - 1, 0; + glVertex $self->{w} - 1, $self->{h} - 1; + glVertex 0 , $self->{h} - 1; + glEnd; + glPopMatrix; + #CFPlus::UI::Label->new (w => $self->{w}, h => $self->{h}, text => $self, fontsize => 0)->_draw; + } +#endif + PUSHMARK (SP); + XPUSHs (self); + PUTBACK; + call_method ("_draw", G_VOID | G_DISCARD); + SPAGAIN; + + glPopMatrix (); + + draw_x = draw_x - x; sv_setnv (draw_x_sv, draw_x); + draw_y = draw_y - y; sv_setnv (draw_y_sv, draw_y); }