mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 04:38:11 +00:00
LibGUI: Add a GFrame class that can be inherited by framey widgets.
This will gather the code for painting sunken/raised frames etc in a single place and make it easier add a bit of pleasant shading to UI's. :^)
This commit is contained in:
parent
b6c5bd3d28
commit
cb296ffede
7 changed files with 110 additions and 12 deletions
43
LibGUI/GFrame.cpp
Normal file
43
LibGUI/GFrame.cpp
Normal file
|
@ -0,0 +1,43 @@
|
|||
#include <LibGUI/GFrame.h>
|
||||
#include <LibGUI/GStyle.h>
|
||||
#include <SharedGraphics/Painter.h>
|
||||
|
||||
GFrame::GFrame(GWidget* parent)
|
||||
: GWidget(parent)
|
||||
{
|
||||
}
|
||||
|
||||
GFrame::~GFrame()
|
||||
{
|
||||
}
|
||||
|
||||
void GFrame::paint_event(GPaintEvent& event)
|
||||
{
|
||||
if (m_shape == Shape::NoFrame)
|
||||
return;
|
||||
|
||||
Painter painter(*this);
|
||||
painter.set_clip_rect(event.rect());
|
||||
|
||||
auto rect = this->rect();
|
||||
|
||||
Color top_left_color;
|
||||
Color bottom_right_color;
|
||||
|
||||
if (m_shadow == Shadow::Raised) {
|
||||
top_left_color = Color::White;
|
||||
bottom_right_color = Color::MidGray;
|
||||
} else if (m_shadow == Shadow::Sunken) {
|
||||
top_left_color = Color::MidGray;
|
||||
bottom_right_color = Color::White;
|
||||
} else if (m_shadow == Shadow::Plain) {
|
||||
top_left_color = Color::MidGray;
|
||||
bottom_right_color = Color::MidGray;
|
||||
}
|
||||
|
||||
painter.draw_line(rect.top_left(), rect.top_right(), top_left_color);
|
||||
painter.draw_line(rect.bottom_left(), rect.bottom_right(), bottom_right_color);
|
||||
|
||||
painter.draw_line(rect.top_left().translated(0, 1), rect.bottom_left().translated(0, -1), top_left_color);
|
||||
painter.draw_line(rect.top_right(), rect.bottom_right().translated(0, -1), bottom_right_color);
|
||||
}
|
33
LibGUI/GFrame.h
Normal file
33
LibGUI/GFrame.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
#pragma once
|
||||
|
||||
#include <LibGUI/GWidget.h>
|
||||
|
||||
class GFrame : public GWidget {
|
||||
public:
|
||||
explicit GFrame(GWidget* parent);
|
||||
virtual ~GFrame() override;
|
||||
|
||||
enum Shadow { Plain, Raised, Sunken };
|
||||
enum Shape { NoFrame, Box, Panel, VerticalLine, HorizontalLine };
|
||||
|
||||
int frame_thickness() const { return m_thickness; }
|
||||
void set_frame_thickness(int thickness) { m_thickness = thickness; }
|
||||
|
||||
Shadow frame_shadow() const { return m_shadow; }
|
||||
void set_frame_shadow(Shadow shadow) { m_shadow = shadow; }
|
||||
|
||||
Shape frame_shape() const { return m_shape; }
|
||||
void set_frame_shape(Shape shape) { m_shape = shape; }
|
||||
|
||||
Rect frame_inner_rect() const { return rect().shrunken(m_thickness * 2, m_thickness * 2); }
|
||||
|
||||
virtual const char* class_name() const override { return "GFrame"; }
|
||||
|
||||
protected:
|
||||
void paint_event(GPaintEvent&) override;
|
||||
|
||||
private:
|
||||
int m_thickness { 0 };
|
||||
Shadow m_shadow { Plain };
|
||||
Shape m_shape { NoFrame };
|
||||
};
|
|
@ -3,12 +3,12 @@
|
|||
#include <SharedGraphics/GraphicsBitmap.h>
|
||||
|
||||
GLabel::GLabel(GWidget* parent)
|
||||
: GWidget(parent)
|
||||
: GFrame(parent)
|
||||
{
|
||||
}
|
||||
|
||||
GLabel::GLabel(const String& text, GWidget* parent)
|
||||
: GWidget(parent)
|
||||
: GFrame(parent)
|
||||
, m_text(text)
|
||||
{
|
||||
}
|
||||
|
@ -32,21 +32,28 @@ void GLabel::set_text(const String& text)
|
|||
|
||||
void GLabel::paint_event(GPaintEvent& event)
|
||||
{
|
||||
GFrame::paint_event(event);
|
||||
|
||||
Painter painter(*this);
|
||||
painter.set_clip_rect(event.rect());
|
||||
|
||||
if (fill_with_background_color())
|
||||
painter.fill_rect({ 0, 0, width(), height() }, background_color());
|
||||
if (m_icon) {
|
||||
if (m_should_stretch_icon) {
|
||||
painter.draw_scaled_bitmap(rect(), *m_icon, m_icon->rect());
|
||||
painter.draw_scaled_bitmap(frame_inner_rect(), *m_icon, m_icon->rect());
|
||||
} else {
|
||||
auto icon_location = rect().center().translated(-(m_icon->width() / 2), -(m_icon->height() / 2));
|
||||
auto icon_location = frame_inner_rect().center().translated(-(m_icon->width() / 2), -(m_icon->height() / 2));
|
||||
painter.blit(icon_location, *m_icon, m_icon->rect());
|
||||
}
|
||||
}
|
||||
if (!text().is_empty())
|
||||
painter.draw_text({ 0, 0, width(), height() }, text(), m_text_alignment, foreground_color());
|
||||
if (!text().is_empty()) {
|
||||
int indent = 0;
|
||||
if (frame_thickness() > 0)
|
||||
indent = font().glyph_width('x') / 2;
|
||||
auto text_rect = frame_inner_rect();
|
||||
text_rect.move_by(indent, 0);
|
||||
text_rect.set_width(text_rect.width() - indent * 2);
|
||||
painter.draw_text(text_rect, text(), m_text_alignment, foreground_color());
|
||||
}
|
||||
}
|
||||
|
||||
void GLabel::size_to_fit()
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#include "GWidget.h"
|
||||
#include <AK/AKString.h>
|
||||
#include <SharedGraphics/Painter.h>
|
||||
#include <LibGUI/GFrame.h>
|
||||
#include <SharedGraphics/TextAlignment.h>
|
||||
|
||||
class GraphicsBitmap;
|
||||
|
||||
class GLabel final : public GWidget {
|
||||
class GLabel final : public GFrame {
|
||||
public:
|
||||
explicit GLabel(GWidget* parent);
|
||||
GLabel(const String& text, GWidget* parent);
|
||||
|
|
|
@ -12,6 +12,9 @@ GStatusBar::GStatusBar(GWidget* parent)
|
|||
set_layout(make<GBoxLayout>(Orientation::Horizontal));
|
||||
layout()->set_margins({ 4, 2, 4, 2 });
|
||||
m_label = new GLabel(this);
|
||||
m_label->set_frame_shadow(GFrame::Shadow::Sunken);
|
||||
m_label->set_frame_shape(GFrame::Shape::Panel);
|
||||
m_label->set_frame_thickness(1);
|
||||
m_label->set_text_alignment(TextAlignment::CenterLeft);
|
||||
}
|
||||
|
||||
|
|
|
@ -492,6 +492,11 @@ Rect GTextEditor::cursor_content_rect() const
|
|||
return { };
|
||||
ASSERT(!m_lines.is_empty());
|
||||
ASSERT(m_cursor.column() <= (current_line().length() + 1));
|
||||
if (is_single_line()) {
|
||||
Rect cursor_rect = { m_horizontal_content_padding + m_cursor.column() * glyph_width(), 0, 1, line_height() };
|
||||
cursor_rect.center_vertically_within(rect());
|
||||
return cursor_rect;
|
||||
}
|
||||
return { m_horizontal_content_padding + m_cursor.column() * glyph_width(), m_cursor.line() * line_height(), 1, line_height() };
|
||||
}
|
||||
|
||||
|
@ -518,6 +523,13 @@ void GTextEditor::scroll_cursor_into_view()
|
|||
|
||||
Rect GTextEditor::line_content_rect(int line_index) const
|
||||
{
|
||||
if (is_single_line()) {
|
||||
Rect line_rect = { m_horizontal_content_padding, 0, content_width(), font().glyph_height() };
|
||||
line_rect.center_vertically_within(rect());
|
||||
// FIXME: This would not be necessary if we knew more about the font and could center it based on baseline and x-height.
|
||||
line_rect.move_by(0, 1);
|
||||
return line_rect;
|
||||
}
|
||||
return {
|
||||
m_horizontal_content_padding,
|
||||
line_index * line_height(),
|
||||
|
|
|
@ -52,6 +52,7 @@ LIBGUI_OBJS = \
|
|||
GItemView.o \
|
||||
GIcon.o \
|
||||
GElapsedTimer.o \
|
||||
GFrame.o \
|
||||
GWindow.o
|
||||
|
||||
OBJS = $(SHAREDGRAPHICS_OBJS) $(LIBGUI_OBJS)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue