#pragma once

#define SLOT_ME() auto& me() { return static_cast<T&>(*this) }

#define SLOT_ATTRIBUTE(type, name) \
	public: \
	auto& name(type in_##name) { \
		name##_ = in_##name; \
		return me(); \
	} \
	const auto& name() const { return name##_; } \
	protected: \
	type name##_{};

#define SLOT_CONTENT() \
	public: \
	auto& set(const std::shared_ptr<mwidget>& in_widget) { \
		widget_ = in_widget; \
		return me(); \
	} \
	const auto& get() const { return widget_; } \
	auto& operator[](const std::shared_ptr<mwidget>& in_widget) { \
		set(in_widget); \
		return me(); \
	} \
	protected: \
	std::shared_ptr<mwidget> widget_{};

#define SLOT_OPTIONAL_ATTRIBUTE(type, name) \
	public: \
	auto& name(type in_##name) { \
		name##_ = in_##name; \
		return me(); \
	} \
	const auto& name() const { return name##_; } \
	auto& has_##name(bool in_has_##name) { \
		has_##name##_ = in_has_##name; \
		return me(); \
	} \
	const auto& has_##name() const { return has_##name##_; } \
	protected: \
	type name##_; \
	bool has_##name##_{};

#define SLOT_SIZE() \
	public: \
	auto& stretch(float in_stretch = 1.f) { \
		size_.set_stretch(in_stretch); \
		return me(); \
	} \
	auto& auto_size() { \
		size_.set_auto_size(); \
		return me(); \
	} \
	const auto& size() const { \
		return size_; \
	} \
	protected: \
		widget_size size_ = widget_size::auto_size();