1 /********************************************************************************
2 * *
3 * S t a t u s L i n e W i d g e t *
4 * *
5 *********************************************************************************
6 * Copyright (C) 1999,2020 by Jeroen van der Zijp. All Rights Reserved. *
7 *********************************************************************************
8 * This library is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU Lesser General Public License as published by *
10 * the Free Software Foundation; either version 3 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This library is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU Lesser General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU Lesser General Public License *
19 * along with this program. If not, see <http://www.gnu.org/licenses/> *
20 ********************************************************************************/
21 #include "xincs.h"
22 #include "fxver.h"
23 #include "fxdefs.h"
24 #include "fxmath.h"
25 #include "FXArray.h"
26 #include "FXHash.h"
27 #include "FXMutex.h"
28 #include "FXStream.h"
29 #include "FXString.h"
30 #include "FXSize.h"
31 #include "FXPoint.h"
32 #include "FXRectangle.h"
33 #include "FXStringDictionary.h"
34 #include "FXSettings.h"
35 #include "FXRegistry.h"
36 #include "FXAccelTable.h"
37 #include "FXFont.h"
38 #include "FXEvent.h"
39 #include "FXWindow.h"
40 #include "FXDCWindow.h"
41 #include "FXApp.h"
42 #include "FXHorizontalFrame.h"
43 #include "FXDragCorner.h"
44 #include "FXStatusLine.h"
45
46
47 /*
48 Notes:
49 - Fallback text is displayed when neither cursor window or
50 target object supply temporary help string.
51 - Show only status line information from same topwindow as where
52 status line is
53 */
54
55 using namespace FX;
56
57 /*******************************************************************************/
58
59 namespace FX {
60
61 // Map
62 FXDEFMAP(FXStatusLine) FXStatusLineMap[]={
63 FXMAPFUNC(SEL_UPDATE,0,FXStatusLine::onUpdate),
64 FXMAPFUNC(SEL_PAINT,0,FXStatusLine::onPaint),
65 FXMAPFUNC(SEL_COMMAND,FXStatusLine::ID_SETSTRINGVALUE,FXStatusLine::onCmdSetStringValue),
66 FXMAPFUNC(SEL_COMMAND,FXStatusLine::ID_GETSTRINGVALUE,FXStatusLine::onCmdGetStringValue),
67 };
68
69
70 // Object implementation
FXIMPLEMENT(FXStatusLine,FXFrame,FXStatusLineMap,ARRAYNUMBER (FXStatusLineMap))71 FXIMPLEMENT(FXStatusLine,FXFrame,FXStatusLineMap,ARRAYNUMBER(FXStatusLineMap))
72
73
74 // Deserialization
75 FXStatusLine::FXStatusLine(){
76 flags|=FLAG_SHOWN;
77 }
78
79
80 // Construct and init
FXStatusLine(FXComposite * p,FXObject * tgt,FXSelector sel)81 FXStatusLine::FXStatusLine(FXComposite* p,FXObject* tgt,FXSelector sel):FXFrame(p,FRAME_SUNKEN|LAYOUT_LEFT|LAYOUT_FILL_Y|LAYOUT_FILL_X,0,0,0,0, 4,4,2,2){
82 flags|=FLAG_SHOWN;
83 status=normal=tr("Ready.");
84 font=getApp()->getNormalFont();
85 textColor=getApp()->getForeColor();
86 textHighlightColor=getApp()->getForeColor();
87 target=tgt;
88 message=sel;
89 }
90
91
92 // Create Window
create()93 void FXStatusLine::create(){
94 FXFrame::create();
95 font->create();
96 }
97
98
99 // Detach Window
detach()100 void FXStatusLine::detach(){
101 FXFrame::detach();
102 font->detach();
103 }
104
105
106 // Get default width; as text changes often, exact content does not matter
getDefaultWidth()107 FXint FXStatusLine::getDefaultWidth(){
108 return padleft+padright+(border<<1)+8;
109 }
110
111
112 // Get default height; just care about font height
getDefaultHeight()113 FXint FXStatusLine::getDefaultHeight(){
114 return font->getFontHeight()+padtop+padbottom+(border<<1);
115 }
116
117
118 // Slightly different from Frame border
onPaint(FXObject *,FXSelector,void * ptr)119 long FXStatusLine::onPaint(FXObject*,FXSelector,void* ptr){
120 FXDCWindow dc(this,(FXEvent*)ptr);
121 dc.setForeground(backColor);
122 dc.setFont(font);
123 dc.fillRectangle(border,border,width-(border<<1),height-(border<<1));
124 if(!status.empty()){
125 FXint ty=padtop+(height-padtop-padbottom-font->getFontHeight())/2;
126 FXint len=status.length();
127 FXint pos=status.find('\n');
128 if(pos>=0){
129 dc.setForeground(textHighlightColor);
130 dc.drawText(padleft,ty+font->getFontAscent(),status.text(),pos);
131 dc.setForeground(textColor);
132 dc.drawText(padleft+font->getTextWidth(status.text(),pos),ty+font->getFontAscent(),status.text()+pos+1,len-pos-1);
133 }
134 else{
135 dc.setForeground(textColor);
136 dc.drawText(padleft,ty+font->getFontAscent(),status.text(),len);
137 }
138 }
139 drawFrame(dc,0,0,width,height);
140 return 1;
141 }
142
143
144 // If the cursor is inside a widget, flash its help text;
145 // Otherwise, unflash back to the regular status message.
onUpdate(FXObject * sender,FXSelector sel,void * ptr)146 long FXStatusLine::onUpdate(FXObject* sender,FXSelector sel,void* ptr){
147 FXWindow *helpsource=getApp()->getCursorWindow();
148
149 // Set background text
150 setText(normal);
151
152 // GUI update callback may set application mode text
153 FXFrame::onUpdate(sender,sel,ptr);
154
155 // Ask the help source for a new status text first, but only if the
156 // statusline's shell is a direct or indirect owner of the help source
157 if(helpsource && getShell()->isOwnerOf(helpsource)){
158 helpsource->handle(this,FXSEL(SEL_QUERY_HELP,0),NULL);
159 }
160 return 1;
161 }
162
163
164 // Update value from a message
onCmdSetStringValue(FXObject *,FXSelector,void * ptr)165 long FXStatusLine::onCmdSetStringValue(FXObject*,FXSelector,void* ptr){
166 setText(*((FXString*)ptr));
167 return 1;
168 }
169
170
171 // Obtain value from text field
onCmdGetStringValue(FXObject *,FXSelector,void * ptr)172 long FXStatusLine::onCmdGetStringValue(FXObject*,FXSelector,void* ptr){
173 *((FXString*)ptr)=getText();
174 return 1;
175 }
176
177
178 // Set currently displayed message
setText(const FXString & text)179 void FXStatusLine::setText(const FXString& text){
180 if(status!=text){
181 status=text;
182 update(border,border,width-(border<<1),height-(border<<1));
183 }
184 }
185
186
187 // Set permanently displayed message
setNormalText(const FXString & text)188 void FXStatusLine::setNormalText(const FXString& text){
189 if(normal!=text){
190 normal=text;
191 update(border,border,width-(border<<1),height-(border<<1));
192 }
193 }
194
195
196 // Change the font
setFont(FXFont * fnt)197 void FXStatusLine::setFont(FXFont* fnt){
198 if(!fnt){ fxerror("%s::setFont: NULL font specified.\n",getClassName()); }
199 if(font!=fnt){
200 font=fnt;
201 recalc();
202 update();
203 }
204 }
205
206
207 // Set text color
setTextColor(FXColor clr)208 void FXStatusLine::setTextColor(FXColor clr){
209 if(textColor!=clr){
210 textColor=clr;
211 update(border,border,width-(border<<1),height-(border<<1));
212 }
213 }
214
215
216 // Set text highlight color
setTextHighlightColor(FXColor clr)217 void FXStatusLine::setTextHighlightColor(FXColor clr){
218 if(textHighlightColor!=clr){
219 textHighlightColor=clr;
220 update(border,border,width-(border<<1),height-(border<<1));
221 }
222 }
223
224
225 // Save object to stream
save(FXStream & store) const226 void FXStatusLine::save(FXStream& store) const {
227 FXFrame::save(store);
228 store << status;
229 store << normal;
230 store << font;
231 store << textColor;
232 store << textHighlightColor;
233 }
234
235
236 // Load object from stream
load(FXStream & store)237 void FXStatusLine::load(FXStream& store){
238 FXFrame::load(store);
239 store >> status;
240 store >> normal;
241 store >> font;
242 store >> textColor;
243 store >> textHighlightColor;
244 }
245
246
247 // Destruct
~FXStatusLine()248 FXStatusLine::~FXStatusLine(){
249 font=(FXFont*)-1L;
250 }
251
252 }
253