1 /*******************************************************************************
2 * Goggles Music Manager *
3 ********************************************************************************
4 * Copyright (C) 2009-2021 by Sander Jansen. All Rights Reserved *
5 * --- *
6 * This program is free software: you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation, either version 3 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program. If not, see http://www.gnu.org/licenses. *
18 ********************************************************************************/
19 #include "gmdefs.h"
20 #include "GMList.h"
21 #include "GMFontDialog.h"
22
23 FXDEFMAP(GMFontDialog) GMFontDialogMap[]={
24 FXMAPFUNC(SEL_UPDATE,GMFontDialog::ID_PITCH,GMFontDialog::onUpdPitch),
25 FXMAPFUNC(SEL_UPDATE,GMFontDialog::ID_SCALABLE,GMFontDialog::onUpdScalable),
26 FXMAPFUNC(SEL_COMMAND,GMFontDialog::ID_PITCH,GMFontDialog::onCmdPitch),
27 FXMAPFUNC(SEL_COMMAND,GMFontDialog::ID_SCALABLE,GMFontDialog::onCmdScalable),
28 FXMAPFUNC(SEL_COMMAND,GMFontDialog::ID_FAMILY,GMFontDialog::onCmdFamily),
29 FXMAPFUNC(SEL_COMMAND,GMFontDialog::ID_STYLE,GMFontDialog::onCmdStyle),
30 FXMAPFUNC(SEL_COMMAND,GMFontDialog::ID_SIZE,GMFontDialog::onCmdSize),
31 FXMAPFUNC(SEL_COMMAND,GMFontDialog::ID_SIZE_TEXT,GMFontDialog::onCmdSizeText)
32 };
33
FXIMPLEMENT(GMFontDialog,FXDialogBox,GMFontDialogMap,ARRAYNUMBER (GMFontDialogMap))34 FXIMPLEMENT(GMFontDialog,FXDialogBox,GMFontDialogMap,ARRAYNUMBER(GMFontDialogMap))
35
36
37 GMFontDialog::GMFontDialog(FXApp * a,const FXString& name,FXuint opts,FXint x,FXint y,FXint w,FXint h) :
38 FXDialogBox(a,name,opts,x,y,w,h,3,3,3,3) {
39 }
40
GMFontDialog(FXWindow * o,const FXString & name,FXuint opts,FXint x,FXint y,FXint w,FXint h)41 GMFontDialog::GMFontDialog(FXWindow* o,const FXString& name,FXuint opts,FXint x,FXint y,FXint w,FXint h) :
42 FXDialogBox(o,name,opts,x,y,w,h,4,4,4,4) {
43 GMScrollFrame *sunken;
44 // FXVerticalFrame * frm;
45
46 FXHorizontalFrame *closebox=new FXHorizontalFrame(this,LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X|PACK_UNIFORM_WIDTH,0,0,0,0,0,0,2,2);
47 new GMButton(closebox," &Accept",nullptr,this,FXDialogBox::ID_ACCEPT,BUTTON_INITIAL|BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK,0,0,0,0, 15,15);
48 new GMButton(closebox," &Cancel ",nullptr,this,FXDialogBox::ID_CANCEL,BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK,0,0,0,0, 15,15);
49
50 FXVerticalFrame * main = new FXVerticalFrame(this,LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0,0,0,0,0,0,0);
51 //frm=new FXVerticalFrame(main,LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_SUNKEN|FRAME_THICK|LAYOUT_BOTTOM,0,0,0,0,0,0,0,0);
52 sunken=new GMScrollFrame(main);
53 sunken->setLayoutHints(LAYOUT_BOTTOM|LAYOUT_FILL_X|LAYOUT_FILL_Y);
54
55 FXScrollWindow *scrollwindow=new FXScrollWindow(sunken,LAYOUT_FILL_X|LAYOUT_FILL_Y);
56 GMScrollArea::replaceScrollbars(scrollwindow);
57 preview=new FXLabel(scrollwindow,"ABCDEFGHIJKLMNOPQRSTUVWXYZ\nabcdefghijklmnopqrstuvwxyz\n0123456789",nullptr,LAYOUT_CENTER_X|LAYOUT_CENTER_Y);
58 preview->setBackColor(getApp()->getBackColor());
59 // new FXLabel(main,"Preview:",nullptr,LAYOUT_BOTTOM);
60
61 FXHorizontalFrame * filterframe = new FXHorizontalFrame(main,LAYOUT_FILL_X|LAYOUT_BOTTOM,0,0,0,0,0,0,3,3,0,0);
62 new FXLabel(filterframe,"Pitch:",nullptr,LABEL_NORMAL|LAYOUT_CENTER_Y,0,0,0,0);
63 pitchlist = new GMListBox(filterframe,this,ID_PITCH);
64 pitchlist->appendItem("Any");
65 pitchlist->appendItem("Fixed",nullptr,(void*)(FXuval)FXFont::Fixed);
66 pitchlist->appendItem("Variable",nullptr,(void*)(FXuval)FXFont::Variable);
67 pitchlist->setNumVisible(3);
68
69 new FXLabel(filterframe," Type:",nullptr,LABEL_NORMAL|LAYOUT_CENTER_Y);
70 scalelist = new GMListBox(filterframe,this,ID_SCALABLE);
71 scalelist->appendItem("Any");
72 scalelist->appendItem("Scalable",nullptr,(void*)(FXuval)FXFont::Scalable);
73 scalelist->setNumVisible(2);
74
75 FXHorizontalFrame * input = new FXHorizontalFrame(main,LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0,0,0,0,0);
76
77 FXVerticalFrame * sizeframe = new FXVerticalFrame(input,LAYOUT_RIGHT|LAYOUT_FILL_Y,0,0,0,0,0,0,0,0,0,0);
78 new FXLabel(sizeframe,"Size:",nullptr,LABEL_NORMAL,0,0,0,0,0,0);
79
80 FXVerticalFrame * sizeinputframe = new FXVerticalFrame(sizeframe,LAYOUT_RIGHT|LAYOUT_FILL_Y,0,0,0,0,0,0,0,0);
81 sizefield=new GMTextField(sizeinputframe,3,this,ID_SIZE_TEXT,TEXTFIELD_NORMAL|TEXTFIELD_INTEGER|LAYOUT_FILL_X);
82 sunken=new GMScrollFrame(sizeinputframe);
83 sizelist=new GMList(sunken,this,ID_SIZE,LAYOUT_FILL_Y|LAYOUT_FILL_X|LIST_SINGLESELECT);
84
85 FXHorizontalFrame * mainframe = new FXHorizontalFrame(input,LAYOUT_LEFT|LAYOUT_FILL_Y|LAYOUT_FILL_X,0,0,0,0,0,0,0,0);
86 FXSpring * familyframe = new FXSpring(mainframe,LAYOUT_FILL_X|LAYOUT_FILL_Y,4,0,0,0,0,0,0,0,0,0,0,0);
87 new FXLabel(familyframe,"Family:",nullptr,LABEL_NORMAL,0,0,0,0);
88 sunken=new GMScrollFrame(familyframe);
89 familylist = new GMList(sunken,this,ID_FAMILY,LAYOUT_FILL_Y|LAYOUT_FILL_X|LIST_BROWSESELECT);
90 familylist->setSortFunc(FXList::ascending);
91
92 FXSpring * styleframe = new FXSpring(mainframe,LAYOUT_FILL_X|LAYOUT_FILL_Y,3,0,0,0,0,0,0,0,0,0,0,0);
93 new FXLabel(styleframe,"Style:",nullptr,LABEL_NORMAL,0,0,0,0);
94 sunken=new GMScrollFrame(styleframe);
95 stylelist=new GMList(sunken,this,ID_STYLE,LAYOUT_FILL_Y|LAYOUT_FILL_X|LIST_BROWSESELECT);
96 stylelist->setSortFunc(FXList::ascending);
97
98 selected = getApp()->getNormalFont()->getActualFontDesc();
99 selected.flags|=FXFont::Scalable;
100 }
101
~GMFontDialog()102 GMFontDialog::~GMFontDialog(){
103 }
104
105
setFontDesc(const FXFontDesc & fontdesc)106 void GMFontDialog::setFontDesc(const FXFontDesc& fontdesc){
107 selected=fontdesc;
108 }
109
getFontDesc() const110 const FXFontDesc& GMFontDialog::getFontDesc() const {
111 return selected;
112 }
113
114
create()115 void GMFontDialog::create() {
116 FXDialogBox::create();
117 listFontFamily();
118 listFontStyle();
119 listFontSize();
120 }
121
122 // Preview
previewFont()123 void GMFontDialog::previewFont(){
124 FXFont *old;
125
126 // Save old font
127 old=previewfont;
128
129 // Get new font
130 previewfont=new FXFont(getApp(),selected);
131
132 // Realize new font
133 previewfont->create();
134
135 // Set new font
136 preview->setFont(previewfont);
137
138 // Delete old font
139 delete old;
140 }
141
142
listFontFamily()143 void GMFontDialog::listFontFamily(){
144 FXFontDesc * fonts=nullptr;
145 FXuint numfonts,f;
146 FXint lastitem=-1,selindex=-1;
147 FXString face,family,pfamily;
148
149 familylist->clearItems();
150 if (FXFont::listFonts(fonts,numfonts,FXString::null,0,0,0,selected.encoding,selected.flags)) {
151 for(f=0;f<numfonts;f++){
152 family=FXString(fonts[f].face).before('[').trimEnd();
153 if (pfamily==family && lastitem>=0) {
154 familylist->setItemText(lastitem,fonts[f-1].face);
155 lastitem=familylist->appendItem(fonts[f].face,nullptr,(void*)(FXuval)fonts[f].flags);
156 }
157 else {
158 lastitem=familylist->appendItem(family,nullptr,(void*)(FXuval)fonts[f].flags);
159 }
160 pfamily.adopt(family);
161 if(compare(selected.face,fonts[f].face)==0) selindex=f;
162 }
163 if(selindex==-1) selindex=0;
164 if(0<familylist->getNumItems()){
165 familylist->setCurrentItem(selindex);
166 familylist->makeItemVisible(selindex);
167 fxstrlcpy(selected.face,familylist->getItemText(selindex).text(),sizeof(selected.face));
168 }
169 FXFREE(&fonts);
170 }
171 familylist->sortItems();
172 }
173
listFontStyle()174 void GMFontDialog::listFontStyle(){
175 FXFontDesc * fonts=nullptr;
176 FXint selindex=-1;
177 FXuint numfonts,f;
178 FXushort wi,ww,lastwi=0,lastww=0,sl,lastsl=0;
179 const FXchar *wgt=nullptr,*slt=nullptr,*wid=nullptr;
180 stylelist->clearItems();
181 if (FXFont::listFonts(fonts,numfonts,selected.face,0,0,0/*selected.weight,selected.slant,selected.setwidth*/,selected.encoding,selected.flags)) {
182 for(f=0;f<numfonts;f++){
183 ww=fonts[f].weight;
184 sl=fonts[f].slant;
185 wi=fonts[f].setwidth;
186 if(ww!=lastww || sl!=lastsl || wi!=lastwi){
187 if(wi!=lastwi){
188 switch(wi){
189 case FXFont::UltraCondensed : wid=tr("Ultra Condensed"); break;
190 case FXFont::ExtraCondensed : wid=tr("Extra Condensed"); break;
191 case FXFont::Condensed : wid=tr("Condensed"); break;
192 case FXFont::SemiCondensed : wid=tr("Semi Condensed"); break;
193 case FXFont::NonExpanded : wid=nullptr; break;
194 case FXFont::SemiExpanded : wid=tr("Semi Expanded"); break;
195 case FXFont::Expanded : wid=tr("Expanded"); break;
196 case FXFont::ExtraExpanded : wid=tr("Extra Expanded"); break;
197 case FXFont::UltraExpanded : wid=tr("Ultra Expanded"); break;
198 default : wid=nullptr; break;
199 }
200 lastwi=wi;
201 }
202 if(ww!=lastww){
203 switch(ww){
204 case FXFont::Thin : wgt=tr("Thin"); break;
205 case FXFont::ExtraLight : wgt=tr("Extra Light"); break;
206 case FXFont::Light : wgt=tr("Light"); break;
207 case FXFont::Normal : wgt=nullptr; break;
208 case FXFont::Medium : wgt=tr("Medium"); break;
209 case FXFont::DemiBold : wgt=tr("Demibold"); break;
210 case FXFont::Bold : wgt=tr("Bold"); break;
211 case FXFont::ExtraBold : wgt=tr("Extra Bold"); break;
212 case FXFont::Black : wgt=tr("Heavy"); break;
213 default : wgt=nullptr; break;
214 }
215 lastww=ww;
216 }
217 if (sl!=lastsl) {
218 switch(sl){
219 case FXFont::ReverseOblique : slt=tr("Reverse Oblique"); break;
220 case FXFont::ReverseItalic : slt=tr("Reverse Italic"); break;
221 case FXFont::Straight : slt=nullptr; break;
222 case FXFont::Italic : slt=tr("Italic"); break;
223 case FXFont::Oblique : slt=tr("Oblique"); break;
224 default : slt=nullptr; break;
225 }
226 lastsl=sl;
227 }
228
229 FXuint style=FXRGB((FXuchar)ww,(FXuchar)sl,(FXuchar)wi);
230 if (wgt && slt && wid)
231 stylelist->appendItem(FXString::value("%s %s %s",wgt,wid,slt),nullptr,(void*)(FXuval)style);
232 else if (wgt && slt)
233 stylelist->appendItem(FXString::value("%s %s",wgt,slt),nullptr,(void*)(FXuval)style);
234 else if (wgt && wid)
235 stylelist->appendItem(FXString::value("%s %s",wgt,wid),nullptr,(void*)(FXuval)style);
236 else if (wid && slt)
237 stylelist->appendItem(FXString::value("%s %s",wid,slt),nullptr,(void*)(FXuval)style);
238 else if (slt)
239 stylelist->appendItem(tr(slt),nullptr,(void*)(FXuval)style);
240 else if (wgt)
241 stylelist->appendItem(tr(wgt),nullptr,(void*)(FXuval)style);
242 else if (wid)
243 stylelist->appendItem(tr(wid),nullptr,(void*)(FXuval)style);
244 else
245 stylelist->appendItem(tr("Normal"),nullptr,(void*)(FXuval)style);
246
247 if (ww==selected.weight && sl==selected.slant && wi==selected.setwidth) {
248 selindex=stylelist->getNumItems()-1;
249 }
250 }
251 }
252 FXFREE(&fonts);
253 if(selindex==-1) selindex=0;
254 if(0<stylelist->getNumItems()){
255 stylelist->setCurrentItem(selindex);
256 FXuint style=(FXuint)(FXuval)stylelist->getItemData(selindex);
257 selected.weight=FXREDVAL(style);
258 selected.slant=FXGREENVAL(style);
259 selected.setwidth=FXBLUEVAL(style);
260 stylelist->makeItemVisible(selindex);
261 //stylelist->sortItems();
262 }
263 }
264 }
265
266
listFontSize()267 void GMFontDialog::listFontSize(){
268 const FXuint sizeint[]={60,80,90,100,110,120,140,160,200,240,300,360,420,480,640,720};
269 FXFontDesc *fonts;
270 FXuint numfonts,f,s,lasts;
271 FXint selindex=-1;
272 sizelist->clearItems();
273 sizefield->setText(FXString::null);
274 FXString string;
275 if(FXFont::listFonts(fonts,numfonts,selected.face,selected.weight,selected.slant,selected.setwidth,selected.encoding,selected.flags)){
276 FXASSERT(0<numfonts);
277 lasts=0;
278 if(fonts[0].flags&FXFont::Scalable){
279 FXuint style=sizelist->getListStyle();
280 style&=~LIST_BROWSESELECT;
281 style|=LIST_SINGLESELECT;
282 sizelist->setListStyle(style);
283 for(f=0; f<ARRAYNUMBER(sizeint); f++){
284 s=sizeint[f];
285 string.format("%g",0.1*s);
286 sizelist->appendItem(string,nullptr,(void*)(FXuval)s);
287 if(selected.size == s) selindex=sizelist->getNumItems()-1;
288 }
289 }
290 else{
291 FXuint style=sizelist->getListStyle();
292 style&=~LIST_SINGLESELECT;
293 style|=LIST_BROWSESELECT;
294 sizelist->setListStyle(style);
295 for(f=0; f<numfonts; f++){
296 s=fonts[f].size;
297 if(s!=lasts){
298 string.format("%.1f",0.1*s);
299 sizelist->appendItem(string,nullptr,(void*)(FXuval)s);
300 if(selected.size==s) selindex=sizelist->getNumItems()-1;
301 lasts=s;
302 }
303 }
304 }
305 if(selindex==-1) selindex=0;
306 if(0<sizelist->getNumItems()){
307 sizelist->selectItem(selindex);
308 sizelist->makeItemVisible(selindex);
309 sizefield->setText(sizelist->getItemText(selindex));
310 selected.size=(FXuint)(FXuval)sizelist->getItemData(selindex);
311 }
312 FXFREE(&fonts);
313 }
314 }
315
onCmdFamily(FXObject *,FXSelector,void * ptr)316 long GMFontDialog::onCmdFamily(FXObject*,FXSelector,void* ptr){
317 fxstrlcpy(selected.face,familylist->getItemText((FXint)(FXival)ptr).text(),sizeof(selected.face));
318 listFontStyle();
319 listFontSize();
320 previewFont();
321 return 1;
322 }
323
onCmdStyle(FXObject *,FXSelector,void * ptr)324 long GMFontDialog::onCmdStyle(FXObject*,FXSelector,void* ptr){
325 FXuint style=(FXuint)(FXuval)stylelist->getItemData((FXint)(FXival)ptr);
326 selected.weight=FXREDVAL(style);
327 selected.slant=FXGREENVAL(style);
328 selected.setwidth=FXBLUEVAL(style);
329 listFontSize();
330 previewFont();
331 return 1;
332 }
333
onCmdSize(FXObject *,FXSelector,void * ptr)334 long GMFontDialog::onCmdSize(FXObject*,FXSelector,void*ptr){
335 selected.size=(FXuint)(FXuval)sizelist->getItemData((FXint)(FXival)ptr);
336 sizefield->setText(sizelist->getItemText((FXint)(FXival)ptr));
337 previewFont();
338 return 1;
339 }
onCmdSizeText(FXObject *,FXSelector,void *)340 long GMFontDialog::onCmdSizeText(FXObject*,FXSelector,void*){
341 selected.size=(FXuint)(10.0f*sizefield->getText().toFloat());
342 if(selected.size<60) selected.size=60;
343 if(selected.size>2400) selected.size=2400;
344 previewFont();
345 return 1;
346 }
347
348
349 // Changed pitch
onCmdPitch(FXObject *,FXSelector,void * ptr)350 long GMFontDialog::onCmdPitch(FXObject*,FXSelector,void*ptr){
351 FXint index=(FXint)(FXival)ptr;
352 selected.flags&=~(FXFont::Fixed|FXFont::Variable);
353 selected.flags|=(FXuint)(FXuval)pitchlist->getItemData(index);
354 listFontFamily();
355 listFontStyle();
356 listFontSize();
357 previewFont();
358 return 1;
359 }
360
onUpdPitch(FXObject * sender,FXSelector,void *)361 long GMFontDialog::onUpdPitch(FXObject*sender,FXSelector,void*){
362 FXint value=(selected.flags&FXFont::Fixed) ? 1 : (selected.flags&FXFont::Variable) ? 2 : 0;
363 sender->handle(this,FXSEL(SEL_COMMAND,ID_SETINTVALUE),&value);
364 return 1;
365 }
366
367 // Changed pitch
onCmdScalable(FXObject *,FXSelector,void * ptr)368 long GMFontDialog::onCmdScalable(FXObject*,FXSelector,void*ptr){
369 FXint index=(FXint)(FXival)ptr;
370 selected.flags&=~(FXFont::Scalable);
371 selected.flags|=(FXuint)(FXuval)scalelist->getItemData(index);
372 listFontFamily();
373 listFontStyle();
374 listFontSize();
375 previewFont();
376 return 1;
377 }
378
onUpdScalable(FXObject * sender,FXSelector,void *)379 long GMFontDialog::onUpdScalable(FXObject*sender,FXSelector,void*){
380 FXint value=(selected.flags&FXFont::Scalable) ? 1 : 0;
381 sender->handle(this,FXSEL(SEL_COMMAND,ID_SETINTVALUE),&value);
382 return 1;
383 }
384