/// Same as draw_buffer, with only the curr_item's full text void ViewDrawingArea::render_full_article() { // Dimensions of drawing area Gtk::Allocation allocation = get_allocation(); const int height = allocation.get_height(); const int width = allocation.get_width(); Cairo::RefPtr<Cairo::Context> cr = _pixmap->create_cairo_context(); cr->reset_clip(); cr->rectangle (0.0, 0.0, width, height); cr->clip(); cr->set_source_rgb (1.0, 1.0, 1.0); cr->paint(); cr->set_source_rgb (0.0, 0.0, 0.0); Item *item = AppContext::get().get_curr_item(); item->make_display_unit(); ItemDisplayUnit *du = item->get_display_unit(); du->render (cr, 0, -_vadj->get_value()); cr->show_page(); double h = du->get_height(); if (h > height) _vadj->set_upper (h - height); else _vadj->set_upper (0); _vadj->set_page_size (height); _vadj->set_step_increment (height * 1.0/16.0); _vadj->set_page_increment (height * 15.0/16.0); _vadj->changed(); }
bool TransparentSlider::on_draw(const Cairo::RefPtr<Cairo::Context>& cr) { auto window = get_window(); Cairo::RectangleInt window_size; Cairo::RectangleInt clip; double x1, y1, x2, y2; cr->get_clip_extents(x1, y1, x2, y2); clip.height = _round(y2-y1); clip.width = _round(x2-x1); clip.x = _round(x1); clip.y = _round(y1); window_size.x = 0; window_size.y = 0; window_size.height = window->get_height(); window_size.width = window->get_width(); cr->save(); if (_SUPPORTS_ALPHA) { cr->set_source_rgba( // transparent _adjustmentRed->get_value(), _adjustmentGreen->get_value(), _adjustmentBlue->get_value(), _adjustmentAlpha->get_value()); } else { cr->set_source_rgb( // opaque _adjustmentRed->get_value(), _adjustmentGreen->get_value(), _adjustmentBlue->get_value()); } cr->set_operator(Cairo::OPERATOR_SOURCE); if (clip.height==window_size.height && clip.width==window_size.width && clip.x==window_size.x && clip.y==window_size.y) { } else { window->invalidate(true); } cr->reset_clip(); cr->paint(); cr->restore(); return Gtk::Window::on_draw(cr); }
void ViewDrawingArea::draw_buffer() { #ifdef DEBUG std::cerr << "VA->val:"<<_vadj->get_value() <<" VA->upper:"<<_vadj->get_upper() << std::endl << std::flush; #endif Feed *feed = AppContext::get().get_feed(); if (feed == NULL) return; if (AppContext::get().get_display_type() == FULL) { render_full_article(); return; } // Dimensions of drawing area Gtk::Allocation allocation = get_allocation(); const int width = allocation.get_width(); const int height = allocation.get_height(); // First determine start item Cairo::RefPtr<Cairo::Context> cr = _pixmap->create_cairo_context(); #ifdef DEBUG /// This code was meant to investigate the 500ms delay with pango /// at start of rendering. if (!_layout_prepared) { Glib::Timer sw; sw.start(); Glib::RefPtr<Pango::Layout> pl = Pango::Layout::create (cr); const char *fonts[] = {"Sans 10", "Sans 14"}; for (unsigned i = 0; i < sizeof(fonts)/sizeof(const char*); ++i) { Pango::FontDescription fdesc (fonts[i]); pl->set_font_description (fdesc); pl->set_width (10 * Pango::SCALE); // force line break pl->set_markup ("<b>Show Us Your Freaky Geek Costumes</b>\nHitting the streets in a scary, tech-themed outfit this Halloween? We want to see it. Find out how your Sergey Brin costume (or is it David Duchovny?) could be featured on Wired News. test\n test"); Pango::Rectangle irect, lrect; pl->get_extents (irect, lrect); } _layout_prepared = true; sw.stop(); unsigned long l; sw.elapsed(l); std::cerr << "Time spent rendering: " << l << " us" << std::endl << std::flush; } #endif const item_list_t items = feed->get_items(); item_list_t::const_iterator start_item; const int n_items = items.size(); double y = 0.0; if (n_items == 0) start_item = items.end(); else { // Set start_item and h int start = static_cast<int> (_vadj->get_value()); double h = 0.0; if (_vadj->get_value() > 0 && _vadj->get_value() == _vadj->get_upper()) { // This will give a blank page when pulling the handle // full down. While unusual, it might make sense with // an ever-growing newslist. y = 0.0; start_item = items.end(); } else { start_item = items.begin(); for (int i = 0; i < start; ++i) ++start_item; if (start < 0) start = 0; double prop = _vadj->get_value() - start; if (prop > 0.0) { (*start_item)->make_display_unit(); ItemDisplayUnit *du = (*start_item)->get_display_unit(); du->layout (cr); h = du->get_height(); } y = - h * prop; #ifdef DEBUG std::cerr << "prop:"<<prop <<" y:"<<y << std::endl << std::flush; #endif } } // clip to the area indicated by the expose event so that we only redraw // the portion of the window that needs to be redrawn cr->reset_clip(); cr->rectangle (0.0, 0.0, width, height); cr->clip(); // Black on white cr->set_source_rgb (1.0, 1.0, 1.0); cr->paint(); cr->set_source_rgb (0.0, 0.0, 0.0); // Render text item_list_t::const_iterator it = start_item; _top_item = *start_item; _topitem_y = y; int count = 0; for (; it != items.end() && y < height; ++it, ++count) { (*it)->make_display_unit(); ItemDisplayUnit *du = (*it)->get_display_unit(); du->render (cr, 0, y); y += du->get_height(); } cr->show_page(); // Scrollbar settings can now be specified _vadj->set_upper (n_items); //_vadj->set_page_size (count - 1 + ); _vadj->set_step_increment (1); _vadj->set_page_increment (count); _vadj->changed(); }
/** * Render the Preview * @param Cairo::Context cr * @return Gtk::Window::on_draw(cr) */ bool Preview::on_draw(const Cairo::RefPtr<Cairo::Context>& cr) { Configuration::Theme theme = Configuration::getTheme(); if (theme.forPreview().enabled()) { cr->set_source_rgba( theme.forPreview().background().red, theme.forPreview().background().green, theme.forPreview().background().blue, theme.forPreview().background().alpha); Utilities::RoundedRectangle(cr, 0, 0, this->get_width(), this->get_height(), theme.forPreview().roundedRatious()); cr->fill(); } if (!m_isActive) { return Gtk::Window::on_draw(cr); } if (m_previewtems.size() < 1) { this->hideMe(); return Gtk::Window::on_draw(cr); } int idx = 0; for (DockItem* item : m_previewtems) { if (item->m_window == NULL || item->m_xid == 0 || !item->visible) continue; int pos_x = 20 + (m_previewWidth * idx); int pos_y = 16; int pos_width = m_previewWidth - DEF_PREVIEW_LEFT_MARGING; int pos_height = 20; cr->set_source_rgba( theme.forPreview().foreground().red, theme.forPreview().foreground().green, theme.forPreview().foreground().blue, theme.forPreview().foreground().alpha); cr->set_line_width(theme.forPreview().lineWith()); if (item->m_imageLoadedRequired) cr->set_line_width(theme.forPreview().lineWith() + 0.5); if (theme.getPreviewBinaryValue() == 0) { Utilities::RoundedRectangle(cr, DEF_PREVIEW_LEFT_MARGING + (m_previewWidth * idx), 16, m_previewWidth, m_previewHeight - DEF_PREVIEW_RIGHT_MARGING, theme.forPreview().roundedRatious()); cr->stroke(); } else { cr->set_line_width(theme.forPreview().lineWith()); int pos_x = DEF_PREVIEW_LEFT_MARGING + (m_previewWidth * idx); int y_pos = 16; int width = m_previewWidth; int height = m_previewHeight; int value = theme.getPreviewBinaryValue(); /* Vertical Left*/ int bit = CHECK_BIT(value, 3); if (bit == 1) { cr->set_line_width(theme.forPreview().lineWith()); cr->move_to(pos_x, y_pos); cr->line_to(pos_x, y_pos); cr->line_to(pos_x, y_pos + (m_previewHeight - DEF_PREVIEW_RIGHT_MARGING)); cr->stroke(); } /* Top */ bit = CHECK_BIT(value, 2); if (bit == 1) { cr->set_line_width(theme.forPreview().lineWith()); cr->move_to(pos_x, y_pos); cr->line_to(pos_x, y_pos); cr->line_to(pos_x + (m_previewWidth), y_pos); cr->stroke(); } /* Right vertical */ bit = CHECK_BIT(value, 1); if (bit == 1) { cr->set_line_width(theme.forPreview().lineWith()); cr->move_to(pos_x + m_previewWidth, y_pos); cr->line_to(pos_x + m_previewWidth, y_pos); cr->line_to(pos_x + m_previewWidth, y_pos + (m_previewHeight - DEF_PREVIEW_RIGHT_MARGING)); cr->stroke(); } bit = CHECK_BIT(value, 0); if (bit == 1) { cr->set_line_width(theme.forPreview().lineWith()); cr->move_to(pos_x, y_pos + (m_previewHeight - DEF_PREVIEW_RIGHT_MARGING)); cr->line_to(pos_x, y_pos + (m_previewHeight - DEF_PREVIEW_RIGHT_MARGING)); cr->line_to(pos_x + m_previewWidth, y_pos + (m_previewHeight - DEF_PREVIEW_RIGHT_MARGING)); cr->stroke(); } } // TEXT // draw title and create clipping rectangle // JG cr->set_source_rgba( theme.forPreviewTitle().background().red, theme.forPreviewTitle().background().green, theme.forPreviewTitle().background().blue, theme.forPreviewTitle().foreground().alpha); cr->rectangle(pos_x, pos_y + 2, pos_width + 2, pos_height); // cr->clip_preserve(); cr->fill(); // JG cr->set_source_rgba( theme.forPreviewTitle().foreground().red, theme.forPreviewTitle().foreground().green, theme.forPreviewTitle().foreground().blue, theme.forPreviewTitle().foreground().alpha); cr->set_line_width(theme.forPreviewTitle().lineWith()); cr->rectangle(pos_x, pos_y + 2, pos_width + 2, pos_height); cr->stroke(); // draw title the clipping rectangle //cr->set_source_rgba(1.0, 1.0, 1.0, 0.0); cr->rectangle(pos_x, pos_y + 2, pos_width, pos_height); cr->clip_preserve(); cr->stroke(); cr->set_source_rgba( theme.forPreviewTitleText().foreground().red, theme.forPreviewTitleText().foreground().green, theme.forPreviewTitleText().foreground().blue, theme.forPreviewTitleText().foreground().alpha); auto layout = create_pango_layout(item->m_titlename); layout->set_font_description(font); //cr->set_source_rgba(1.0, 1.0, 1.0, 1.0); // white text cr->move_to(pos_x, pos_y + 2); layout->show_in_cairo_context(cr); cr->reset_clip(); // Reset the clipping if (item->m_imageLoadedRequired) { GdkPixbuf *scaledpb = getScaledPixbuf(item); if (scaledpb == nullptr) { continue; } // show the loaded image. showPreview(cr, scaledpb, idx); // Checks if the image have movement. if (item->isMovementDetected(scaledpb) && !item->m_isDynamic) { item->m_isDynamic = true; } // if no movement has been detected, means that the image // is static and we don't need to reload it again if (++item->m_frames > 3 && !item->m_isDynamic) { item->m_scaledPixbuf = scaledpb; item->m_frames = 0; item->m_imageLoadedRequired = false; } // if the image is static do not unreference the scaledpb. if (item->m_imageLoadedRequired) g_object_unref(scaledpb); } else { // show the loaded static image. showPreview(cr, item->m_scaledPixbuf, idx); } // selector if (m_currentIndex == idx) { // rectangle background selector pos_x = DEF_PREVIEW_LEFT_MARGING + (m_previewWidth * m_currentIndex); pos_y = 16; pos_width = m_previewWidth + 1; pos_height = m_previewHeight - DEF_PREVIEW_RIGHT_MARGING; if (m_previewtems.size() > 1) { cr->set_source_rgba( theme.forPreviewSelector().background().red, theme.forPreviewSelector().background().green, theme.forPreviewSelector().background().blue, theme.forPreviewSelector().background().alpha); Utilities::RoundedRectangle(cr, pos_x, pos_y, pos_width, pos_height, theme.forPreviewSelector().roundedRatious()); cr->fill(); } cr->set_source_rgba( theme.forPreviewSelector().foreground().red, theme.forPreviewSelector().foreground().green, theme.forPreviewSelector().foreground().blue, theme.forPreviewSelector().foreground().alpha); cr->set_line_width(theme.forPreviewSelector().lineWith()); if (theme.getPreviewSelectorBinaryValue() == 0) { Utilities::RoundedRectangle(cr, pos_x, pos_y, pos_width, pos_height, theme.forPreviewSelector().roundedRatious()); cr->stroke(); } else { int value = theme.getPreviewSelectorBinaryValue(); // /* Vertical Left*/ int bit = CHECK_BIT(value, 3); if (bit == 1) { cr->move_to(pos_x, pos_y); cr->line_to(pos_x, pos_y); cr->line_to(pos_x, pos_y + (pos_height)); cr->stroke(); } /* Top */ bit = CHECK_BIT(value, 2); if (bit == 1) { cr->move_to(pos_x, pos_y); cr->line_to(pos_x, pos_y); cr->line_to(pos_x + (pos_width), pos_y); cr->stroke(); } /* Right vertical */ bit = CHECK_BIT(value, 1); if (bit == 1) { cr->move_to(pos_x + pos_width, pos_y); cr->line_to(pos_x + pos_width, pos_y); cr->line_to(pos_x + pos_width, pos_y + (m_previewHeight - DEF_PREVIEW_RIGHT_MARGING)); cr->stroke(); } bit = CHECK_BIT(value, 0); if (bit == 1) { cr->move_to(pos_x, pos_y + (m_previewHeight - DEF_PREVIEW_RIGHT_MARGING)); cr->line_to(pos_x, pos_y + (m_previewHeight - DEF_PREVIEW_RIGHT_MARGING)); cr->line_to(pos_x + m_previewWidth, pos_y + (m_previewHeight - DEF_PREVIEW_RIGHT_MARGING)); cr->stroke(); } } cr->set_source_rgba( theme.forPreviewSelectorClose().background().red, theme.forPreviewSelectorClose().background().green, theme.forPreviewSelectorClose().background().blue, theme.forPreviewSelectorClose().background().alpha); pos_x = (m_previewWidth - 5) + (m_previewWidth * m_currentIndex); cr->move_to(pos_x + 3, DEF_PREVIEW_RIGHT_MARGING); cr->rectangle(pos_x, 18, DEF_PREVIEW_LEFT_MARGING, DEF_PREVIEW_LEFT_MARGING + 2); cr->fill(); cr->set_source_rgba( theme.forPreviewSelectorClose().foreground().red, theme.forPreviewSelectorClose().foreground().green, theme.forPreviewSelectorClose().foreground().blue, theme.forPreviewSelectorClose().foreground().alpha); cr->set_line_width(theme.forPreviewSelectorClose().lineWith()); // Close X text cr->move_to(pos_x + 3, DEF_PREVIEW_RIGHT_MARGING - 1); cr->show_text("X"); } idx++; } return Gtk::Window::on_draw(cr); }