2 * Copyright (C) 2009 by Aiwota Programmer
3 * aiwotaprog@tetteke.tk
5 * This file is part of Dialektos.
7 * Dialektos is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * Dialektos is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Dialektos. If not, see <http://www.gnu.org/licenses/>.
21 #include "text_view_layoutable.hxx"
23 #include <boost/foreach.hpp>
24 #include "text_view_drawing_set.hxx"
25 #include "text_line.hxx"
26 #include "text_element_res_num_map.hxx"
27 #include "text_element_id_map.hxx"
36 Layoutable::Layoutable():
37 Scrollable(), pango_layout_(create_pango_layout("")), line_list_(),
38 id_map_(new text_element::IDMap),
39 res_num_map_(new text_element::ResNumMap),
43 Layoutable::~Layoutable() {
46 void Layoutable::add_line(TextLine* line) {
47 line_list_.push_back(line);
50 void Layoutable::relayout() {
51 const int width = get_width();
53 set.layout = pango_layout_;
56 BOOST_FOREACH(TextLine& line, line_list_) {
65 adjustment_.set_upper(set.y);
68 bool Layoutable::on_configure_event(GdkEventConfigure* event) {
71 else if (width_ != get_width()) {
72 const gdouble value = adjustment_.get_value();
73 TextLine* first_line = 0;
75 BOOST_FOREACH(TextLine& line, line_list_) {
76 if (y + line.get_height() > value) {
80 y += line.get_height();
82 gdouble delta = y - value;
87 BOOST_FOREACH(TextLine& line, line_list_) {
88 if (&line == first_line) {
91 y += line.get_height();
93 adjustment_.set_value(y - delta);
95 return Scrollable::on_configure_event(event);
99 const TextLine* Layoutable::get_text_line(const gdouble y_adj) const {
102 BOOST_FOREACH(const TextLine& line, line_list_) {
103 const gdouble height = line.get_height();
104 if (sum + height > y_adj)
111 const TextLine* Layoutable::get_nearest_text_line(gdouble& y_adj) const {
112 if (line_list_.empty()) return 0;
116 return &line_list_[0];
118 if (y_adj > adjustment_.get_upper()) {
119 y_adj = adjustment_.get_upper();
120 return &line_list_.back();
123 return get_text_line(y_adj);
126 const text_element::Plain* Layoutable::get_text_element(const gdouble x,
127 const gdouble y_adj) const {
129 const TextLine* line = get_text_line(y_adj);
131 return line->get_text_element(x, y_adj);
134 const text_element::Plain* Layoutable::get_nearest_text_element(
135 gdouble& x, gdouble& y_adj) const {
137 const TextLine* line = get_nearest_text_line(y_adj);
139 return line->get_nearest_text_element(x, y_adj);
143 } // namespace text_view
145 } // namespace dialektos