#include "BaseElementView.h" #include "control/settings/Settings.h" #include "gui/Shadow.h" #include "BackgroundSelectDialogBase.h" #include "Util.h" BaseElementView::BaseElementView(int id, BackgroundSelectDialogBase* dlg): dlg(dlg), id(id) { this->widget = gtk_drawing_area_new(); gtk_widget_show(this->widget); gtk_widget_set_events(widget, GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK); g_signal_connect(this->widget, "draw", G_CALLBACK(drawCallback), this); g_signal_connect(this->widget, "button-press-event", G_CALLBACK(mouseButtonPressCallback), this); } BaseElementView::~BaseElementView() { gtk_widget_destroy(this->widget); if (this->crBuffer) { cairo_surface_destroy(this->crBuffer); this->crBuffer = nullptr; } } auto BaseElementView::drawCallback(GtkWidget* widget, cairo_t* cr, BaseElementView* element) -> gboolean { element->paint(cr); return true; } auto BaseElementView::mouseButtonPressCallback(GtkWidget* widget, GdkEventButton* event, BaseElementView* element) -> gboolean { element->dlg->setSelected(element->id); return true; } void BaseElementView::setSelected(bool selected) { if (this->selected == selected) { return; } this->selected = selected; repaint(); } void BaseElementView::repaint() { if (this->crBuffer) { cairo_surface_destroy(this->crBuffer); this->crBuffer = nullptr; } gtk_widget_queue_draw(this->widget); } void BaseElementView::paint(cairo_t* cr) { GtkAllocation alloc; gtk_widget_get_allocation(this->widget, &alloc); if (this->crBuffer == nullptr) { this->crBuffer = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, alloc.width, alloc.height); int width = getContentWidth(); int height = getContentHeight(); cairo_t* cr2 = cairo_create(this->crBuffer); cairo_set_source_rgb(cr2, 1, 1, 1); cairo_rectangle(cr2, 0, 0, alloc.width, alloc.height); cairo_fill(cr2); cairo_matrix_t defaultMatrix = {0}; cairo_get_matrix(cr2, &defaultMatrix); cairo_translate(cr2, Shadow::getShadowTopLeftSize() + 2, Shadow::getShadowTopLeftSize() + 2); paintContents(cr2); cairo_set_operator(cr2, CAIRO_OPERATOR_SOURCE); cairo_set_matrix(cr2, &defaultMatrix); cairo_set_operator(cr2, CAIRO_OPERATOR_ATOP); if (this->selected) { // Draw border Util::cairo_set_source_rgbi(cr2, dlg->getSettings()->getBorderColor()); cairo_set_line_width(cr2, 2); cairo_set_line_cap(cr2, CAIRO_LINE_CAP_BUTT); cairo_set_line_join(cr2, CAIRO_LINE_JOIN_BEVEL); cairo_rectangle(cr2, Shadow::getShadowTopLeftSize() + 1.5, Shadow::getShadowTopLeftSize() + 1.5, width + 2, height + 2); cairo_stroke(cr2); Shadow::drawShadow(cr2, Shadow::getShadowTopLeftSize(), Shadow::getShadowTopLeftSize(), width + 4, height + 4); } else { Shadow::drawShadow(cr2, Shadow::getShadowTopLeftSize() + 2, Shadow::getShadowTopLeftSize() + 2, width, height); } cairo_destroy(cr2); } cairo_set_source_surface(cr, this->crBuffer, 0, 0); cairo_paint(cr); } auto BaseElementView::getWidget() -> GtkWidget* { updateSize(); return this->widget; } auto BaseElementView::getWidth() -> int { calcSize(); return getContentWidth() + Shadow::getShadowBottomRightSize() + Shadow::getShadowTopLeftSize() + 4; } auto BaseElementView::getHeight() -> int { calcSize(); return getContentHeight() + Shadow::getShadowBottomRightSize() + Shadow::getShadowTopLeftSize() + 4; } void BaseElementView::calcSize() { // Not implemented in the base class } void BaseElementView::updateSize() { gtk_widget_set_size_request(this->widget, this->getWidth(), this->getHeight()); }