GTK + 3渲染具有选择背景色的矩形 [英] GTK+3 render rectangle with selection background color

查看:98
本文介绍了GTK + 3渲染具有选择背景色的矩形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在GTK + 3中,如何用选择的背景色渲染矩形.我找不到任何API可以做到这一点:

How is it possible to render a rectangle with the background color of selections in GTK+3. I cannot find any API to do that:

static gboolean draw_callback (GtkWidget *widget, cairo_t *cr, gpointer data)
    {
    auto state=reinterpret_cast<State*>(data);
    auto width = gtk_widget_get_allocated_width (widget);
    auto height = gtk_widget_get_allocated_height (widget);

    auto context = gtk_widget_get_style_context (widget);
    gtk_render_background(context,cr,0,0,width,height);

    cairo_rectangle(cr,0,height*(1.0 - state->max),width,height*(state->max - state->min));
    cairo_set_source_rgb(cr, 0.05,0.6,0.15); //What color should be used here?
    cairo_fill (cr);

    cairo_set_source_rgb(cr,0.01,0.3,0.07); //And here
    auto mid=height*(1.0 - 0.5*(state->min + state->max));
    cairo_move_to(cr,0, mid);
    cairo_line_to(cr,width,mid);
    cairo_stroke(cr);

    return FALSE;
    }

推荐答案

好,这是我的技巧:

ColorRGBA get_ambient_color(GtkWidget* widget)
    {
    auto surface=cairo_image_surface_create(CAIRO_FORMAT_ARGB32,4,4);
    auto cr=cairo_create(surface);
    while(widge!=NULL)
        {
        auto context=gtk_widget_get_style_context(widget));
        gtk_render_background(context,cr,0,0,1,1);
        cairo_surface_flush(surface);
        auto content=cairo_image_surface_get_data(surface);
        if(content[3]==255)
            {
            auto ret=ColorRGBA{content[2]/255.0f,content[1]/255.0f,content[0]/255.0f,content[3]/255.0f};
            cairo_destroy(cr);
            cairo_surface_destroy(surface);
            return ret;
            }
    //  Surface is not opaque yet. Continue to parent container.
        widget_handle=gtk_widget_get_parent(GTK_WIDGET(widget_handle));
        }
    cairo_destroy(cr);
    cairo_surface_destroy(surface);
    return ColorRGBA{1.0f,1.0f,1.0f,1.0f};
    }

这似乎使我无法说服人们,为什么您需要使用环境颜色,所以这里有两个用例:

It seams that I have failed to convince people, why you need the ambient colour, so here are two use-cases:

  1. 确定我们是否使用深色/浅色主题.对于某些应用程序,这已足够.仅当主题支持暗/亮模式时,才可以查询状态.这证明了实际结果.

  1. Determine if we are using a dark/light theme. For some applications, this is sufficient. Querying the state only works if the theme supports dark/light modes. This proves the actual result.

用作模拟全局照明的输入颜色.小部件的阴影应受周围环境的影响,因此应受其名称的影响.另一个好名字是get_average_background. Themers:请不要使用高对比度的渐变.

Use as input colour for simulating global illumination. The shading of widgets should be affected by the ambient, hence the name. Another good name would be get_average_background. Themers: please don't use gradients with high contrast.

案例1:情节

现在,您说游标和功能图的颜色应该是可调整的.这简直是​​不可能的:该绘图小部件的用户可以根据需要添加任意数量的曲线和光标,而区分它们的最简单方法是使用不同的颜色.

Now you say that the colour of cursors and function graphs should be themable. That is simply not possible: The user of this plot widget can add as many curves and cursors as he wishes, and the easiest way to differentiate them is to use distinct colours.

曲线和光标的亮度如何?如果背景较暗,则曲线应为浅色,反之亦然.而应该选择什么背景呢?理想情况下,某些东西会关闭父窗口小部件的背景,但是如果主题是常规的,则白色代表浅色,黑色代表深色将起作用.您是否注意到第二个图中的曲线更暗?

What about curve and cursor lightness? If the background is dark, then the curve should be light and vice versa. And what background should be chosen? Ideally, something close the the background of the parent widget, but if the theme is regular, white for light, and black for dark would work. Do you notice that the curves are darker in the second figure?

使用以下技术,我创建了一个开关,看起来与通过Cycles路径跟踪器呈现的开关完全一样. 这是在Gtk + 2中实现的,但是算法是相同的.

With the following technique, I have created a switch that looks exactly as if it were rendered through the Cycles path tracer. This is implemented in Gtk+2, but the algorithm is the same.

GtkAllocation alloc;
gtk_widget_get_allocation(widget,&alloc);

auto width=alloc.width;
auto context=CairoContext( gdk_cairo_create(gtk_widget_get_window(widget)) );

auto w_in=cairo_image_surface_get_width(light);
auto h_in=cairo_image_surface_get_height(light);

// Render direct lighting
auto surf_temp=CairoSurface( cairo_image_surface_create(CAIRO_FORMAT_ARGB32,w_in,h_in) );
auto context_temp=CairoContext( cairo_create(surf_temp) );
cairo_set_source_surface(context_temp,light,0,0);
cairo_set_operator(context_temp,CAIRO_OPERATOR_OVER);
cairo_paint(context_temp);

//Render ambient reflections
auto surf_temp_2=CairoSurface( cairo_image_surface_create(CAIRO_FORMAT_ARGB32,w_in,h_in) );
auto context_temp_2=CairoContext( cairo_create(surf_temp_2) );
cairo_set_source_surface(context_temp_2,background,0,0);
cairo_set_operator(context_temp_2,CAIRO_OPERATOR_OVER);
cairo_paint(context_temp_2);

cairo_set_operator(context_temp_2,CAIRO_OPERATOR_MULTIPLY);
//Multiply reflections with the background color
cairo_set_source_rgb(context_temp_2, color_bg.r, color_bg.g, color_bg.b);
cairo_rectangle(context_temp_2, 0, 0, w_in, h_in);
cairo_mask_surface(context_temp_2,surf_temp,0,0);

//Add the results
cairo_set_source_surface(context_temp,surf_temp_2,0,0);
cairo_set_operator(context_temp,CAIRO_OPERATOR_ADD);
cairo_mask_surface(context_temp,surf_temp,0,0);

//Scale and move things into place
auto s=static_cast<double>(width)/static_cast<double>(w_in);
cairo_translate(context,alloc.x,alloc.y);
cairo_scale(context,s,s);
cairo_set_source_surface(context,surf_temp,0,0);
cairo_set_operator(context,CAIRO_OPERATOR_OVER);
cairo_paint(context);

想法

第一个示例归结为当前缺少的明/暗查询.也许不需要查询颜色即可完成此工作,但是在渲染背景时,必须有一个控制形状和混合模式的API.例如,要渲染环境反射,我使用乘法而不是结束.另外,gtk_render_background似乎是无操作的,因为GtkDrawingArea的不透明度为零(这就是我需要循环的原因).为了有用,它必须使用屏幕上显示的背景,而不是当前小部件的背景.

Thoughts

The first example boils down to a light/dark query which is currently missing. Maybe querying colours is not required for this to work, but then there has to be an API controlling the shape and blending mode when rendering the background. For example, to render the ambient reflection, I use multiply rather than over. Also, gtk_render_background appears to be a no-op, since GtkDrawingArea has zero opacity (that's why I needed the loop). To be useful, it must use the background as it appears on screen, not the background of the current widget.

这篇关于GTK + 3渲染具有选择背景色的矩形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆