]> git.lyx.org Git - lyx.git/blob - src/frontends/screen.C
send UpdatableInset down the way of the Dodo
[lyx.git] / src / frontends / screen.C
1 /**
2  * \file screen.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author John Levon
7  *
8  * Full author contact details are available in file CREDITS.
9  *
10  * Splash screen code added by Angus Leeming
11  */
12
13 #include <config.h>
14
15 #include "screen.h"
16 #include "font_metrics.h"
17 #include "lyx_gui.h"
18 #include "Painter.h"
19 #include "WorkArea.h"
20
21 #include "BufferView.h"
22 #include "buffer.h"
23 #include "bufferparams.h"
24 #include "coordcache.h"
25 #include "cursor.h"
26 #include "debug.h"
27 #include "language.h"
28 #include "LColor.h"
29 #include "lyxfont.h"
30 #include "lyxrc.h"
31 #include "lyxrow.h"
32 #include "lyxtext.h"
33 #include "metricsinfo.h"
34 #include "paragraph.h"
35 #include "rowpainter.h"
36 #include "version.h"
37
38 #include "graphics/GraphicsImage.h"
39 #include "graphics/GraphicsLoader.h"
40
41 #include "support/filetools.h" // LibFileSearch
42
43 #include <boost/utility.hpp>
44 #include <boost/bind.hpp>
45 #include <boost/signals/trackable.hpp>
46
47 using lyx::support::LibFileSearch;
48
49 using std::endl;
50 using std::min;
51 using std::max;
52 using std::string;
53
54
55 namespace {
56
57 class SplashScreen : boost::noncopyable, boost::signals::trackable {
58 public:
59         /// This is a singleton class. Get the instance.
60         static SplashScreen const & get();
61         ///
62         lyx::graphics::Image const * image() const { return loader_.image(); }
63         ///
64         string const & text() const { return text_; }
65         ///
66         LyXFont const & font() const { return font_; }
67         ///
68         void connect(lyx::graphics::Loader::slot_type const & slot) const {
69                 loader_.connect(slot);
70         }
71         ///
72         void startLoading() const {
73                 if (loader_.status() == lyx::graphics::WaitingToLoad)
74                         loader_.startLoading();
75         }
76
77 private:
78         /** Make the c-tor private so we can control how many objects
79          *  are instantiated.
80          */
81         SplashScreen();
82
83         ///
84         lyx::graphics::Loader loader_;
85         /// The text to be written on top of the pixmap
86         string const text_;
87         /// in this font...
88         LyXFont font_;
89 };
90
91
92 SplashScreen const & SplashScreen::get()
93 {
94         static SplashScreen singleton;
95         return singleton;
96 }
97
98
99 SplashScreen::SplashScreen()
100         : text_(lyx_version ? lyx_version : "unknown")
101 {
102         if (!lyxrc.show_banner)
103                 return;
104
105         string const file = LibFileSearch("images", "banner", "ppm");
106         if (file.empty())
107                 return;
108
109         // The font used to display the version info
110         font_.setFamily(LyXFont::SANS_FAMILY);
111         font_.setSeries(LyXFont::BOLD_SERIES);
112         font_.setSize(LyXFont::SIZE_NORMAL);
113         font_.setColor(LColor::yellow);
114
115         // Load up the graphics file
116         loader_.reset(file);
117 }
118
119 } // namespace anon
120
121
122 LyXScreen::LyXScreen()
123         : greyed_out_(true), cursor_visible_(false)
124 {
125         // Start loading the pixmap as soon as possible
126         if (lyxrc.show_banner) {
127                 SplashScreen const & splash = SplashScreen::get();
128                 splash.connect(boost::bind(&LyXScreen::checkAndGreyOut, this));
129                 splash.startLoading();
130         }
131 }
132
133
134 LyXScreen::~LyXScreen()
135 {
136 }
137
138
139 void LyXScreen::checkAndGreyOut()
140 {
141         if (greyed_out_)
142                 greyOut();
143 }
144
145
146 void LyXScreen::showCursor(BufferView & bv)
147 {
148         if (cursor_visible_)
149                 return;
150
151         if (!bv.available())
152                 return;
153
154         Cursor_Shape shape = BAR_SHAPE;
155
156         LyXText const & text = *bv.getLyXText();
157         LyXFont const & realfont = text.real_current_font;
158         BufferParams const & bp = bv.buffer()->params();
159         bool const samelang = realfont.language() == bp.language;
160         bool const isrtl = realfont.isVisibleRightToLeft();
161
162         if (!samelang || isrtl != bp.language->RightToLeft()) {
163                 shape = L_SHAPE;
164                 if (isrtl)
165                         shape = REVERSED_L_SHAPE;
166         }
167
168         // The ERT language hack needs fixing up
169         if (realfont.language() == latex_language)
170                 shape = BAR_SHAPE;
171
172         LyXFont const font = bv.cursor().getFont();
173         int const asc = font_metrics::maxAscent(font);
174         int const des = font_metrics::maxDescent(font);
175         int h = asc + des;
176         int x = 0;
177         int y = 0;
178         bv.cursor().getPos(x, y);
179         y -= asc;
180         //lyxerr << "LyXScreen::showCursor x: " << x << " y: " << y << endl;
181
182         // if it doesn't touch the screen, don't try to show it
183         if (y + h < 0 || y >= workarea().workHeight())
184                 return;
185
186         cursor_visible_ = true;
187         showCursor(x, y, h, shape);
188 }
189
190
191 void LyXScreen::hideCursor()
192 {
193         if (!cursor_visible_)
194                 return;
195
196         cursor_visible_ = false;
197         removeCursor();
198 }
199
200
201 void LyXScreen::toggleCursor(BufferView & bv)
202 {
203         if (cursor_visible_)
204                 hideCursor();
205         else
206                 showCursor(bv);
207 }
208
209
210 void LyXScreen::prepareCursor()
211 {
212         cursor_visible_ = false;
213 }
214
215
216 void LyXScreen::redraw(BufferView & bv, ViewMetricsInfo const & vi)
217 {
218         greyed_out_ = false;
219         workarea().getPainter().start();
220         paintText(bv, vi);
221         lyxerr[Debug::DEBUG] << "Redraw screen" << endl;
222         expose(0, 0, workarea().workWidth(), workarea().workHeight());
223         workarea().getPainter().end();
224         theCoords.doneUpdating();
225 }
226
227
228 void LyXScreen::greyOut()
229 {
230         greyed_out_ = true;
231         workarea().getPainter().start();
232
233         workarea().getPainter().fillRectangle(0, 0,
234                 workarea().workWidth(),
235                 workarea().workHeight(),
236                 LColor::bottomarea);
237
238         // Add a splash screen to the centre of the work area
239         SplashScreen const & splash = SplashScreen::get();
240         lyx::graphics::Image const * const splash_image = splash.image();
241         if (splash_image) {
242                 int const w = splash_image->getWidth();
243                 int const h = splash_image->getHeight();
244
245                 int x = (workarea().workWidth() - w) / 2;
246                 int y = (workarea().workHeight() - h) / 2;
247
248                 workarea().getPainter().image(x, y, w, h, *splash_image);
249
250                 x += 260;
251                 y += 265;
252
253                 workarea().getPainter().text(x, y, splash.text(), splash.font());
254         }
255         expose(0, 0, workarea().workWidth(), workarea().workHeight());
256         workarea().getPainter().end();
257 }