mirror of
				https://github.com/slint-ui/slint.git
				synced 2025-11-03 21:24:17 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			162 lines
		
	
	
	
		
			5.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			162 lines
		
	
	
	
		
			5.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
// Copyright © SixtyFPS GmbH <info@slint-ui.com>
 | 
						|
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-commercial
 | 
						|
 | 
						|
#pragma once
 | 
						|
#include <string_view>
 | 
						|
#include "slint_color.h"
 | 
						|
#include "slint_brush_internal.h"
 | 
						|
#include "slint_string.h"
 | 
						|
 | 
						|
namespace slint {
 | 
						|
 | 
						|
namespace private_api {
 | 
						|
 | 
						|
using cbindgen_private::types::GradientStop;
 | 
						|
 | 
						|
/// \private
 | 
						|
/// LinearGradientBrush represents a gradient for a brush that is a linear sequence of color stops,
 | 
						|
/// that are aligned at a specific angle.
 | 
						|
class LinearGradientBrush
 | 
						|
{
 | 
						|
public:
 | 
						|
    /// Constructs an empty linear gradient with no color stops.
 | 
						|
    LinearGradientBrush() = default;
 | 
						|
    /// Constructs a new linear gradient with the specified \a angle. The color stops will be
 | 
						|
    /// constructed from the stops array pointed to be \a firstStop, with the length \a stopCount.
 | 
						|
    LinearGradientBrush(float angle, const GradientStop *firstStop, int stopCount)
 | 
						|
        : inner(make_linear_gradient(angle, firstStop, stopCount))
 | 
						|
    {
 | 
						|
    }
 | 
						|
 | 
						|
    /// Returns the linear gradient's angle in degrees.
 | 
						|
    float angle() const
 | 
						|
    {
 | 
						|
        // The gradient's first stop is a fake stop to store the angle
 | 
						|
        return inner[0].position;
 | 
						|
    }
 | 
						|
 | 
						|
    /// Returns the number of gradient stops.
 | 
						|
    int stopCount() const { return int(inner.size()) - 1; }
 | 
						|
 | 
						|
    /// Returns a pointer to the first gradient stop; undefined if the gradient has not stops.
 | 
						|
    const GradientStop *stopsBegin() const { return inner.begin() + 1; }
 | 
						|
    /// Returns a pointer past the last gradient stop. The returned pointer cannot be dereferenced,
 | 
						|
    /// it can only be used for comparison.
 | 
						|
    const GradientStop *stopsEnd() const { return inner.end(); }
 | 
						|
 | 
						|
private:
 | 
						|
    cbindgen_private::types::LinearGradientBrush inner;
 | 
						|
 | 
						|
    friend class slint::Brush;
 | 
						|
 | 
						|
    static SharedVector<private_api::GradientStop>
 | 
						|
    make_linear_gradient(float angle, const GradientStop *firstStop, int stopCount)
 | 
						|
    {
 | 
						|
        SharedVector<private_api::GradientStop> gradient;
 | 
						|
        gradient.push_back({ Color::from_argb_encoded(0).inner, angle });
 | 
						|
        for (int i = 0; i < stopCount; ++i, ++firstStop)
 | 
						|
            gradient.push_back(*firstStop);
 | 
						|
        return gradient;
 | 
						|
    }
 | 
						|
};
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
/// Brush is used to declare how to fill or outline shapes, such as rectangles, paths or text. A
 | 
						|
/// brush is either a solid color or a linear gradient.
 | 
						|
class Brush
 | 
						|
{
 | 
						|
public:
 | 
						|
    /// Constructs a new brush that is a transparent color.
 | 
						|
    Brush() : Brush(Color {}) { }
 | 
						|
    /// Constructs a new brush that is of color \a color.
 | 
						|
    Brush(const Color &color) : data(Inner::SolidColor(color.inner)) { }
 | 
						|
    /// \private
 | 
						|
    /// Constructs a new brush that is the gradient \a gradient.
 | 
						|
    Brush(const private_api::LinearGradientBrush &gradient)
 | 
						|
        : data(Inner::LinearGradient(gradient.inner))
 | 
						|
    {
 | 
						|
    }
 | 
						|
 | 
						|
    /// Returns the color of the brush. If the brush is a gradient, this function returns the color
 | 
						|
    /// of the first stop.
 | 
						|
    inline Color color() const;
 | 
						|
 | 
						|
    /// Returns a new version of this brush that has the brightness increased
 | 
						|
    /// by the specified factor. This is done by calling Color::brighter on
 | 
						|
    /// all the colors of this brush.
 | 
						|
    inline Brush brighter(float factor) const;
 | 
						|
    /// Returns a new version of this color that has the brightness decreased
 | 
						|
    /// by the specified factor. This is done by calling Color::darker on
 | 
						|
    /// all the colors of this brush.
 | 
						|
    inline Brush darker(float factor) const;
 | 
						|
 | 
						|
    /// Returns true if \a a is equal to \a b. If \a a holds a color, then \a b must also hold a
 | 
						|
    /// color that is identical to \a a's color. If it holds a gradient, then the gradients must be
 | 
						|
    /// identical. Returns false if the brushes differ in what they hold or their respective color
 | 
						|
    /// or gradient are not equal.
 | 
						|
    friend bool operator==(const Brush &a, const Brush &b) { return a.data == b.data; }
 | 
						|
    /// Returns false if \a is not equal to \a b; true otherwise.
 | 
						|
    friend bool operator!=(const Brush &a, const Brush &b) { return a.data != b.data; }
 | 
						|
 | 
						|
private:
 | 
						|
    using Tag = cbindgen_private::types::Brush::Tag;
 | 
						|
    using Inner = cbindgen_private::types::Brush;
 | 
						|
    Inner data;
 | 
						|
};
 | 
						|
 | 
						|
Color Brush::color() const
 | 
						|
{
 | 
						|
    Color result;
 | 
						|
    switch (data.tag) {
 | 
						|
    case Tag::SolidColor: {
 | 
						|
        result.inner = data.solid_color._0;
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case Tag::LinearGradient:
 | 
						|
        if (data.linear_gradient._0.size() > 1) {
 | 
						|
            result.inner = data.linear_gradient._0[1].color;
 | 
						|
        }
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    return result;
 | 
						|
}
 | 
						|
 | 
						|
inline Brush Brush::brighter(float factor) const
 | 
						|
{
 | 
						|
    Brush result = *this;
 | 
						|
    switch (data.tag) {
 | 
						|
    case Tag::SolidColor: {
 | 
						|
        cbindgen_private::types::slint_color_brighter(&data.solid_color._0, factor,
 | 
						|
                                                      &result.data.solid_color._0);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case Tag::LinearGradient:
 | 
						|
        for (std::size_t i = 1; i < data.linear_gradient._0.size(); ++i) {
 | 
						|
            cbindgen_private::types::slint_color_brighter(&data.linear_gradient._0[i].color, factor,
 | 
						|
                                                          &result.data.linear_gradient._0[i].color);
 | 
						|
        }
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    return result;
 | 
						|
}
 | 
						|
 | 
						|
inline Brush Brush::darker(float factor) const
 | 
						|
{
 | 
						|
    Brush result = *this;
 | 
						|
    switch (data.tag) {
 | 
						|
    case Tag::SolidColor: {
 | 
						|
        cbindgen_private::types::slint_color_darker(&data.solid_color._0, factor,
 | 
						|
                                                    &result.data.solid_color._0);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case Tag::LinearGradient:
 | 
						|
        for (std::size_t i = 1; i < data.linear_gradient._0.size(); ++i) {
 | 
						|
            cbindgen_private::types::slint_color_darker(&data.linear_gradient._0[i].color, factor,
 | 
						|
                                                        &result.data.linear_gradient._0[i].color);
 | 
						|
        }
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    return result;
 | 
						|
}
 | 
						|
}
 |