Serenity Operating System
at master 80 lines 2.4 kB view raw
1/* 2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> 3 * Copyright (c) 2022, the SerenityOS developers. 4 * 5 * SPDX-License-Identifier: BSD-2-Clause 6 */ 7 8#pragma once 9 10#include <LibGUI/TextPosition.h> 11 12namespace GUI { 13 14class TextRange { 15public: 16 TextRange() = default; 17 TextRange(TextPosition const& start, TextPosition const& end) 18 : m_start(start) 19 , m_end(end) 20 { 21 } 22 23 bool is_valid() const { return m_start.is_valid() && m_end.is_valid() && m_start != m_end; } 24 void clear() 25 { 26 m_start = {}; 27 m_end = {}; 28 } 29 30 TextPosition& start() { return m_start; } 31 TextPosition& end() { return m_end; } 32 TextPosition const& start() const { return m_start; } 33 TextPosition const& end() const { return m_end; } 34 35 size_t line_count() const { return normalized_end().line() - normalized_start().line() + 1; } 36 37 TextRange normalized() const { return TextRange(normalized_start(), normalized_end()); } 38 39 void set_start(TextPosition const& position) { m_start = position; } 40 void set_end(TextPosition const& position) { m_end = position; } 41 42 void set(TextPosition const& start, TextPosition const& end) 43 { 44 m_start = start; 45 m_end = end; 46 } 47 48 bool operator==(TextRange const& other) const 49 { 50 return m_start == other.m_start && m_end == other.m_end; 51 } 52 53 bool contains(TextPosition const& position) const 54 { 55 if (!(position.line() > m_start.line() || (position.line() == m_start.line() && position.column() >= m_start.column()))) 56 return false; 57 if (!(position.line() < m_end.line() || (position.line() == m_end.line() && position.column() <= m_end.column()))) 58 return false; 59 return true; 60 } 61 62private: 63 TextPosition normalized_start() const { return m_start < m_end ? m_start : m_end; } 64 TextPosition normalized_end() const { return m_start < m_end ? m_end : m_start; } 65 66 TextPosition m_start {}; 67 TextPosition m_end {}; 68}; 69 70} 71 72template<> 73struct AK::Formatter<GUI::TextRange> : AK::Formatter<FormatString> { 74 ErrorOr<void> format(FormatBuilder& builder, GUI::TextRange const& value) 75 { 76 if (value.is_valid()) 77 return Formatter<FormatString>::format(builder, "{}-{}"sv, value.start(), value.end()); 78 return builder.put_string("GUI::TextRange(Invalid)"sv); 79 } 80};