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