void gDC::disableSpinner() { ASSERT(m_spinner_saved); /* restore background */ m_pixmap->blit(*m_spinner_saved, eRect(m_spinner_pos.topLeft(), eSize()), gRegion(m_spinner_pos), 0); }
void gDC::incrementSpinner() { ASSERT(m_spinner_saved); static int blub; blub++; #if 0 int i; for (i = 0; i < 5; ++i) { int x = i * 20 + m_spinner_pos.left(); int y = m_spinner_pos.top(); int col = ((blub - i) * 30) % 256; m_pixmap->fill(eRect(x, y, 10, 10), gRGB(col, col, col)); } #endif m_spinner_temp->blit(*m_spinner_saved, eRect(0, 0, 0, 0), eRect(ePoint(0, 0), m_spinner_pos.size())); if (m_spinner_pic[m_spinner_i]) m_spinner_temp->blit(*m_spinner_pic[m_spinner_i], eRect(0, 0, 0, 0), eRect(ePoint(0, 0), m_spinner_pos.size()), gPixmap::blitAlphaBlend); m_pixmap->blit(*m_spinner_temp, eRect(m_spinner_pos.topLeft(), eSize()), gRegion(m_spinner_pos), 0); m_spinner_i++; m_spinner_i %= m_spinner_num; }
void eWidgetDesktop::createBufferForWidget(eWidget *widget, int layer) { removeBufferForWidget(widget, layer); eWidgetDesktopCompBuffer *comp = widget->m_comp_buffer[layer] = new eWidgetDesktopCompBuffer; eDebug("[eWidgetDesktop] create buffer for widget layer %d, %d x %d\n", layer, widget->size().width(), widget->size().height()); eRect bbox = eRect(widget->position(), widget->size()); comp->m_position = bbox.topLeft(); comp->m_dirty_region = gRegion(eRect(ePoint(0, 0), bbox.size())); comp->m_screen_size = bbox.size(); /* TODO: configurable bit depth. */ /* clone palette. FIXME. */ ePtr<gPixmap> pm = new gPixmap(comp->m_screen_size, 32, 1), pm_screen; pm->surface->clut.data = new gRGB[256]; pm->surface->clut.colors = 256; pm->surface->clut.start = 0; m_screen.m_dc->getPixmap(pm_screen); memcpy(pm->surface->clut.data, pm_screen->surface->clut.data, 256 * sizeof(gRGB)); comp->m_dc = new gDC(pm); }
void gDC::enableSpinner() { ASSERT(m_spinner_saved); /* save the background to restore it later. We need to negative position because we want to blit from the middle of the screen. */ m_spinner_saved->blit(*m_pixmap, eRect(-m_spinner_pos.topLeft(), eSize()), gRegion(eRect(ePoint(0, 0), m_spinner_saved->size())), 0); incrementSpinner(); }
void eWidgetDesktop::resize(eSize size) { m_screen.m_dirty_region = gRegion(eRect(ePoint(0, 0), size)); m_screen.m_screen_size = size; #ifdef USE_LIBVUGLES2 gPainter painter(m_screen.m_dc); painter.setView(size); #endif }
eWidgetDesktop::eWidgetDesktop(eSize size): m_mainloop(0) { m_screen.m_dirty_region = gRegion(eRect(ePoint(0, 0), size)); m_screen.m_screen_size = size; m_require_redraw = 0; m_style_id = 0; CONNECT(gRC::getInstance()->notify, eWidgetDesktop::notify); setCompositionMode(cmImmediate); }
int eWidget::event(int event, void *data, void *data2) { switch (event) { case evtPaint: { gPainter &painter = *(gPainter*)data2; // eDebug("eWidget::evtPaint"); // dumpRegion(*(gRegion*)data); if (!isTransparent()) { if (!m_have_background_color) { ePtr<eWindowStyle> style; if (!getStyle(style)) style->paintBackground(painter, ePoint(0, 0), size()); } else { painter.setBackgroundColor(m_background_color); painter.clear(); } } else { eWidget *w = this; while (w && !w->m_have_background_color) w = w->m_parent; if (w) painter.setBackgroundColor(w->m_background_color); } break; } case evtKey: break; case evtWillChangeSize: m_size = *static_cast<eSize*>(data); break; case evtChangedSize: m_clip_region = gRegion(eRect(ePoint(0, 0), m_size)); break; case evtParentChangedPosition: for (ePtrList<eWidget>::iterator i(m_childs.begin()); i != m_childs.end(); ++i) i->event(evtParentChangedPosition); break; case evtFocusGot: m_focus_owner = (eWidget*)data; break; case evtFocusLost: m_focus_owner = 0; break; default: return -1; } return 0; }
void eWidgetDesktop::paintBackground(eWidgetDesktopCompBuffer *comp) { if (!comp) return; comp->m_dirty_region &= comp->m_background_region; gPainter painter(comp->m_dc); painter.resetClip(comp->m_dirty_region); painter.setBackgroundColor(comp->m_background_color); painter.clear(); comp->m_dirty_region = gRegion(); }
void eWidgetDesktop::calcWidgetClipRegion(eWidget *widget, gRegion &parent_visible) { /* start with our clip region, clipped with the parent's */ if (widget->m_vis & eWidget::wVisShow) { widget->m_visible_region = widget->m_clip_region; widget->m_visible_region.moveBy(widget->position()); widget->m_visible_region &= parent_visible; // in parent space! if (!widget->isTransparent()) /* remove everything this widget will contain from parent's visible list, unless widget is transparent. */ parent_visible -= widget->m_visible_region; // will remove child regions too! /* now prepare for recursing to childs */ widget->m_visible_region.moveBy(-widget->position()); // now in local space } else widget->m_visible_region = gRegion(); widget->m_visible_with_childs = widget->m_visible_region; /* add childs in reverse (Z) order - we're going from front-to-bottom here. */ ePtrList<eWidget>::iterator i(widget->m_childs.end()); for (;;) { if (i != widget->m_childs.end()) { if (i->m_vis & eWidget::wVisShow) calcWidgetClipRegion(*i, widget->m_visible_region); else clearVisibility(*i); } if (i == widget->m_childs.begin()) break; --i; } }
void gDC::exec(const gOpcode *o) { switch (o->opcode) { case gOpcode::setBackgroundColor: m_background_color = o->parm.setColor->color; m_background_color_rgb = getRGB(m_background_color); delete o->parm.setColor; break; case gOpcode::setForegroundColor: m_foreground_color = o->parm.setColor->color; m_foreground_color_rgb = getRGB(m_foreground_color); delete o->parm.setColor; break; case gOpcode::setBackgroundColorRGB: if (m_pixmap->needClut()) m_background_color = m_pixmap->surface->clut.findColor(o->parm.setColorRGB->color); m_background_color_rgb = o->parm.setColorRGB->color; delete o->parm.setColorRGB; break; case gOpcode::setForegroundColorRGB: if (m_pixmap->needClut()) m_foreground_color = m_pixmap->surface->clut.findColor(o->parm.setColorRGB->color); m_foreground_color_rgb = o->parm.setColorRGB->color; delete o->parm.setColorRGB; break; case gOpcode::setFont: m_current_font = o->parm.setFont->font; o->parm.setFont->font->Release(); delete o->parm.setFont; break; case gOpcode::renderText: { ePtr<eTextPara> para = new eTextPara(o->parm.renderText->area); int flags = o->parm.renderText->flags; ASSERT(m_current_font); para->setFont(m_current_font); para->renderString(o->parm.renderText->text, (flags & gPainter::RT_WRAP) ? RS_WRAP : 0, o->parm.renderText->border); if (o->parm.renderText->text) free(o->parm.renderText->text); if (flags & gPainter::RT_HALIGN_LEFT) para->realign(eTextPara::dirLeft); else if (flags & gPainter::RT_HALIGN_RIGHT) para->realign(eTextPara::dirRight); else if (flags & gPainter::RT_HALIGN_CENTER) para->realign((flags & gPainter::RT_WRAP) ? eTextPara::dirCenter : eTextPara::dirCenterIfFits); else if (flags & gPainter::RT_HALIGN_BLOCK) para->realign(eTextPara::dirBlock); else para->realign(eTextPara::dirBidi); ePoint offset = m_current_offset; if (o->parm.renderText->flags & gPainter::RT_VALIGN_CENTER) { eRect bbox = para->getBoundBox(); int vcentered_top = o->parm.renderText->area.top() + ((o->parm.renderText->area.height() - bbox.height()) / 2); int correction = vcentered_top - bbox.top(); // Only center if it fits, don't push text out the top if (correction > 0) { offset += ePoint(0, correction); } } else if (o->parm.renderText->flags & gPainter::RT_VALIGN_BOTTOM) { eRect bbox = para->getBoundBox(); int correction = o->parm.renderText->area.height() - bbox.height() - 2; offset += ePoint(0, correction); } if (o->parm.renderText->border) { para->blit(*this, offset, m_background_color_rgb, o->parm.renderText->bordercolor, true); para->blit(*this, offset, o->parm.renderText->bordercolor, m_foreground_color_rgb); } else { para->blit(*this, offset, m_background_color_rgb, m_foreground_color_rgb); } delete o->parm.renderText; break; } case gOpcode::renderPara: { o->parm.renderPara->textpara->blit(*this, o->parm.renderPara->offset + m_current_offset, m_background_color_rgb, m_foreground_color_rgb); o->parm.renderPara->textpara->Release(); delete o->parm.renderPara; break; } case gOpcode::fill: { eRect area = o->parm.fill->area; area.moveBy(m_current_offset); gRegion clip = m_current_clip & area; if (m_pixmap->needClut()) m_pixmap->fill(clip, m_foreground_color); else m_pixmap->fill(clip, m_foreground_color_rgb); delete o->parm.fill; break; } case gOpcode::fillRegion: { o->parm.fillRegion->region.moveBy(m_current_offset); gRegion clip = m_current_clip & o->parm.fillRegion->region; if (m_pixmap->needClut()) m_pixmap->fill(clip, m_foreground_color); else m_pixmap->fill(clip, m_foreground_color_rgb); delete o->parm.fillRegion; break; } case gOpcode::clear: if (m_pixmap->needClut()) m_pixmap->fill(m_current_clip, m_background_color); else m_pixmap->fill(m_current_clip, m_background_color_rgb); delete o->parm.fill; break; case gOpcode::blit: { gRegion clip; // this code should be checked again but i'm too tired now o->parm.blit->position.moveBy(m_current_offset); if (o->parm.blit->clip.valid()) { o->parm.blit->clip.moveBy(m_current_offset); clip.intersect(gRegion(o->parm.blit->clip), m_current_clip); } else clip = m_current_clip; m_pixmap->blit(*o->parm.blit->pixmap, o->parm.blit->position, clip, o->parm.blit->flags); o->parm.blit->pixmap->Release(); delete o->parm.blit; break; } case gOpcode::setPalette: if (o->parm.setPalette->palette->start > m_pixmap->surface->clut.colors) o->parm.setPalette->palette->start = m_pixmap->surface->clut.colors; if (o->parm.setPalette->palette->colors > (m_pixmap->surface->clut.colors-o->parm.setPalette->palette->start)) o->parm.setPalette->palette->colors = m_pixmap->surface->clut.colors-o->parm.setPalette->palette->start; if (o->parm.setPalette->palette->colors) memcpy(m_pixmap->surface->clut.data+o->parm.setPalette->palette->start, o->parm.setPalette->palette->data, o->parm.setPalette->palette->colors*sizeof(gRGB)); delete[] o->parm.setPalette->palette->data; delete o->parm.setPalette->palette; delete o->parm.setPalette; break; case gOpcode::mergePalette: m_pixmap->mergePalette(*o->parm.mergePalette->target); o->parm.mergePalette->target->Release(); delete o->parm.mergePalette; break; case gOpcode::line: { ePoint start = o->parm.line->start + m_current_offset, end = o->parm.line->end + m_current_offset; if (m_pixmap->needClut()) m_pixmap->line(m_current_clip, start, end, m_foreground_color); else m_pixmap->line(m_current_clip, start, end, m_foreground_color_rgb); delete o->parm.line; break; } case gOpcode::addClip: m_clip_stack.push(m_current_clip); o->parm.clip->region.moveBy(m_current_offset); m_current_clip &= o->parm.clip->region; delete o->parm.clip; break; case gOpcode::setClip: o->parm.clip->region.moveBy(m_current_offset); m_current_clip = o->parm.clip->region & eRect(ePoint(0, 0), m_pixmap->size()); delete o->parm.clip; break; case gOpcode::popClip: if (!m_clip_stack.empty()) { m_current_clip = m_clip_stack.top(); m_clip_stack.pop(); } break; case gOpcode::setOffset: if (o->parm.setOffset->rel) m_current_offset += o->parm.setOffset->value; else m_current_offset = o->parm.setOffset->value; delete o->parm.setOffset; break; case gOpcode::waitVSync: break; case gOpcode::flip: break; case gOpcode::flush: break; case gOpcode::sendShow: break; case gOpcode::sendHide: break; #ifdef USE_LIBVUGLES2 case gOpcode::setView: break; #endif case gOpcode::enableSpinner: enableSpinner(); break; case gOpcode::disableSpinner: disableSpinner(); break; case gOpcode::incrementSpinner: incrementSpinner(); break; default: eFatal("illegal opcode %d. expect memory leak!", o->opcode); } }
void eWidgetDesktop::recalcClipRegions(eWidget *root) { if (m_comp_mode == cmImmediate) { gRegion background_before = m_screen.m_background_region; m_screen.m_background_region = gRegion(eRect(ePoint(0, 0), m_screen.m_screen_size)); for (ePtrList<eWidget>::iterator i(m_root.begin()); i != m_root.end(); ++i) { if (!(i->m_vis & eWidget::wVisShow)) { clearVisibility(i); continue; } gRegion visible_before = i->m_visible_with_childs; calcWidgetClipRegion(*i, m_screen.m_background_region); gRegion redraw = (i->m_visible_with_childs - visible_before) | (visible_before - i->m_visible_with_childs); redraw.moveBy(i->position()); invalidate(redraw); } gRegion redraw = (background_before - m_screen.m_background_region) | (m_screen.m_background_region - background_before); invalidate(redraw); } else if (m_comp_mode == cmBuffered) { if (!(root->m_vis & eWidget::wVisShow)) { clearVisibility(root); for (int i = 0; i < MAX_LAYER; ++i) removeBufferForWidget(root, i); return; } for (int i = 0; i < MAX_LAYER; ++i) { eWidgetDesktopCompBuffer *comp = root->m_comp_buffer[i]; /* TODO: layers might not be required to have the screen size, for memory reasons. */ if ((i == 0 && !comp) || (comp && (root->size() != comp->m_screen_size))) createBufferForWidget(root, 0); comp = root->m_comp_buffer[i]; /* it might have changed. */ if (!comp) continue; /* WAIT, don't we need to invalidate,whatever */ /* CHECKME: don't we need to recalculate everything? after all, our buffer has changed and is likely to be cleared */ gRegion visible_before = root->m_visible_with_childs; comp->m_background_region = gRegion(eRect(comp->m_position, comp->m_screen_size)); gRegion visible_new = root->m_visible_with_childs - visible_before; gRegion visible_lost = visible_before - root->m_visible_with_childs; visible_new.moveBy(root->position()); visible_lost.moveBy(root->position()); invalidate(visible_new, root, i); invalidate(visible_lost, root, i); calcWidgetClipRegion(root, comp->m_background_region); } } }
void eWidgetDesktop::clearVisibility(eWidget *widget) { widget->m_visible_with_childs = gRegion(); for (ePtrList<eWidget>::iterator i(widget->m_childs.begin()); i != widget->m_childs.end(); ++i) clearVisibility(*i); }
void eWidgetDesktop::resize(eSize size) { m_screen.m_dirty_region = gRegion(eRect(ePoint(0, 0), size)); m_screen.m_screen_size = size; }