1 //------------------------------------------------------------------------------
2 // emFileManTheme.cpp
3 //
4 // Copyright (C) 2010-2011,2014-2016,2019 Oliver Hamann.
5 //
6 // Homepage: http://eaglemode.sourceforge.net/
7 //
8 // This program is free software: you can redistribute it and/or modify it under
9 // the terms of the GNU General Public License version 3 as published by the
10 // Free Software Foundation.
11 //
12 // This program is distributed in the hope that it will be useful, but WITHOUT
13 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 // FOR A PARTICULAR PURPOSE. See the GNU General Public License version 3 for
15 // more details.
16 //
17 // You should have received a copy of the GNU General Public License version 3
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 //------------------------------------------------------------------------------
20
21 #include <emCore/emInstallInfo.h>
22 #include <emCore/emRes.h>
23 #include <emFileMan/emFileManTheme.h>
24
25
26 //==============================================================================
27 //=============================== emFileManTheme ===============================
28 //==============================================================================
29
GetThemesDirPath()30 emString emFileManTheme::GetThemesDirPath()
31 {
32 return emGetInstallPath(EM_IDT_RES,"emFileMan","themes");
33 }
34
35
36 const char * emFileManTheme::ThemeFileEnding = ".emFileManTheme";
37
38
Acquire(emRootContext & rootContext,const emString & name)39 emRef<emFileManTheme> emFileManTheme::Acquire(
40 emRootContext & rootContext, const emString & name
41 )
42 {
43 EM_IMPL_ACQUIRE_COMMON(emFileManTheme,rootContext,name)
44 }
45
46
ImageFileRec(emFileManTheme * parent,const char * varIdentifier,emRootContext & rootContext)47 emFileManTheme::ImageFileRec::ImageFileRec(
48 emFileManTheme * parent, const char * varIdentifier, emRootContext & rootContext
49 )
50 : emStringRec(parent,varIdentifier),
51 emRecListener(this),
52 RootContext(rootContext)
53 {
54 }
55
56
GetImage() const57 const emImage & emFileManTheme::ImageFileRec::GetImage() const
58 {
59 if (Image.IsEmpty() && !Get().IsEmpty()) {
60 ((emFileManTheme::ImageFileRec*)this)->Image=emGetResImage(
61 RootContext,
62 emGetChildPath(
63 emGetParentPath(
64 ((const emFileManTheme*)GetParent())->GetInstallPath()
65 ),
66 Get()
67 )
68 );
69 }
70 return Image;
71 }
72
73
OnRecChanged()74 void emFileManTheme::ImageFileRec::OnRecChanged()
75 {
76 Image.Clear();
77 }
78
79
GetFormatName() const80 const char * emFileManTheme::GetFormatName() const
81 {
82 return "emFileManTheme";
83 }
84
85
emFileManTheme(emContext & context,const emString & name)86 emFileManTheme::emFileManTheme(emContext & context, const emString & name)
87 : emConfigModel(context,name),
88 emStructRec(),
89 DisplayName(this,"DisplayName"),
90 DisplayIcon(this,"DisplayIcon"),
91 BackgroundColor(this,"BackgroundColor"),
92 SourceSelectionColor(this,"SourceSelectionColor"),
93 TargetSelectionColor(this,"TargetSelectionColor"),
94 NormalNameColor(this,"NormalNameColor",emColor(0,0,0,255),true),
95 ExeNameColor(this,"ExeNameColor",emColor(0,0,0,255),true),
96 DirNameColor(this,"DirNameColor",emColor(0,0,0,255),true),
97 FifoNameColor(this,"FifoNameColor",emColor(0,0,0,255),true),
98 BlkNameColor(this,"BlkNameColor",emColor(0,0,0,255),true),
99 ChrNameColor(this,"ChrNameColor",emColor(0,0,0,255),true),
100 SockNameColor(this,"SockNameColor",emColor(0,0,0,255),true),
101 OtherNameColor(this,"OtherNameColor",emColor(0,0,0,255),true),
102 PathColor(this,"PathColor",emColor(0,0,0,255),true),
103 SymLinkColor(this,"SymLinkColor",emColor(0,0,0,255),true),
104 LabelColor(this,"LabelColor",emColor(0,0,0,255),true),
105 InfoColor(this,"InfoColor",emColor(0,0,0,255),true),
106 FileContentColor(this,"FileContentColor"),
107 DirContentColor(this,"DirContentColor"),
108 Height(this,"Height"),
109 BackgroundX(this,"BackgroundX"),
110 BackgroundY(this,"BackgroundY"),
111 BackgroundW(this,"BackgroundW"),
112 BackgroundH(this,"BackgroundH"),
113 BackgroundRX(this,"BackgroundRX"),
114 BackgroundRY(this,"BackgroundRY"),
115 OuterBorderX(this,"OuterBorderX"),
116 OuterBorderY(this,"OuterBorderY"),
117 OuterBorderW(this,"OuterBorderW"),
118 OuterBorderH(this,"OuterBorderH"),
119 OuterBorderL(this,"OuterBorderL"),
120 OuterBorderT(this,"OuterBorderT"),
121 OuterBorderR(this,"OuterBorderR"),
122 OuterBorderB(this,"OuterBorderB"),
123 OuterBorderImg(this,"OuterBorderImg",GetRootContext()),
124 OuterBorderImgL(this,"OuterBorderImgL"),
125 OuterBorderImgT(this,"OuterBorderImgT"),
126 OuterBorderImgR(this,"OuterBorderImgR"),
127 OuterBorderImgB(this,"OuterBorderImgB"),
128 NameX(this,"NameX"),
129 NameY(this,"NameY"),
130 NameW(this,"NameW"),
131 NameH(this,"NameH"),
132 NameAlignment(this,"NameAlignment"),
133 PathX(this,"PathX"),
134 PathY(this,"PathY"),
135 PathW(this,"PathW"),
136 PathH(this,"PathH"),
137 PathAlignment(this,"PathAlignment"),
138 InfoX(this,"InfoX"),
139 InfoY(this,"InfoY"),
140 InfoW(this,"InfoW"),
141 InfoH(this,"InfoH"),
142 InfoAlignment(this,"InfoAlignment"),
143 FileInnerBorderX(this,"FileInnerBorderX"),
144 FileInnerBorderY(this,"FileInnerBorderY"),
145 FileInnerBorderW(this,"FileInnerBorderW"),
146 FileInnerBorderH(this,"FileInnerBorderH"),
147 FileInnerBorderL(this,"FileInnerBorderL"),
148 FileInnerBorderT(this,"FileInnerBorderT"),
149 FileInnerBorderR(this,"FileInnerBorderR"),
150 FileInnerBorderB(this,"FileInnerBorderB"),
151 FileInnerBorderImg(this,"FileInnerBorderImg",GetRootContext()),
152 FileInnerBorderImgL(this,"FileInnerBorderImgL"),
153 FileInnerBorderImgT(this,"FileInnerBorderImgT"),
154 FileInnerBorderImgR(this,"FileInnerBorderImgR"),
155 FileInnerBorderImgB(this,"FileInnerBorderImgB"),
156 FileContentX(this,"FileContentX"),
157 FileContentY(this,"FileContentY"),
158 FileContentW(this,"FileContentW"),
159 FileContentH(this,"FileContentH"),
160 DirInnerBorderX(this,"DirInnerBorderX"),
161 DirInnerBorderY(this,"DirInnerBorderY"),
162 DirInnerBorderW(this,"DirInnerBorderW"),
163 DirInnerBorderH(this,"DirInnerBorderH"),
164 DirInnerBorderL(this,"DirInnerBorderL"),
165 DirInnerBorderT(this,"DirInnerBorderT"),
166 DirInnerBorderR(this,"DirInnerBorderR"),
167 DirInnerBorderB(this,"DirInnerBorderB"),
168 DirInnerBorderImg(this,"DirInnerBorderImg",GetRootContext()),
169 DirInnerBorderImgL(this,"DirInnerBorderImgL"),
170 DirInnerBorderImgT(this,"DirInnerBorderImgT"),
171 DirInnerBorderImgR(this,"DirInnerBorderImgR"),
172 DirInnerBorderImgB(this,"DirInnerBorderImgB"),
173 DirContentX(this,"DirContentX"),
174 DirContentY(this,"DirContentY"),
175 DirContentW(this,"DirContentW"),
176 DirContentH(this,"DirContentH"),
177 AltX(this,"AltX"),
178 AltY(this,"AltY"),
179 AltW(this,"AltW"),
180 AltH(this,"AltH"),
181 AltLabelX(this,"AltLabelX"),
182 AltLabelY(this,"AltLabelY"),
183 AltLabelW(this,"AltLabelW"),
184 AltLabelH(this,"AltLabelH"),
185 AltLabelAlignment(this,"AltLabelAlignment"),
186 AltPathX(this,"AltPathX"),
187 AltPathY(this,"AltPathY"),
188 AltPathW(this,"AltPathW"),
189 AltPathH(this,"AltPathH"),
190 AltPathAlignment(this,"AltPathAlignment"),
191 AltAltX(this,"AltAltX"),
192 AltAltY(this,"AltAltY"),
193 AltAltW(this,"AltAltW"),
194 AltAltH(this,"AltAltH"),
195 AltInnerBorderX(this,"AltInnerBorderX"),
196 AltInnerBorderY(this,"AltInnerBorderY"),
197 AltInnerBorderW(this,"AltInnerBorderW"),
198 AltInnerBorderH(this,"AltInnerBorderH"),
199 AltInnerBorderL(this,"AltInnerBorderL"),
200 AltInnerBorderT(this,"AltInnerBorderT"),
201 AltInnerBorderR(this,"AltInnerBorderR"),
202 AltInnerBorderB(this,"AltInnerBorderB"),
203 AltInnerBorderImg(this,"AltInnerBorderImg",GetRootContext()),
204 AltInnerBorderImgL(this,"AltInnerBorderImgL"),
205 AltInnerBorderImgT(this,"AltInnerBorderImgT"),
206 AltInnerBorderImgR(this,"AltInnerBorderImgR"),
207 AltInnerBorderImgB(this,"AltInnerBorderImgB"),
208 AltContentX(this,"AltContentX"),
209 AltContentY(this,"AltContentY"),
210 AltContentW(this,"AltContentW"),
211 AltContentH(this,"AltContentH"),
212 MinContentVW(this,"MinContentVW"),
213 MinAltVW(this,"MinAltVW"),
214 DirPaddingL(this,"DirPaddingL"),
215 DirPaddingT(this,"DirPaddingT"),
216 DirPaddingR(this,"DirPaddingR"),
217 DirPaddingB(this,"DirPaddingB"),
218 LnkPaddingL(this,"LnkPaddingL"),
219 LnkPaddingT(this,"LnkPaddingT"),
220 LnkPaddingR(this,"LnkPaddingR"),
221 LnkPaddingB(this,"LnkPaddingB")
222 {
223 PostConstruct(
224 *this,
225 emGetChildPath(GetThemesDirPath(), name + ThemeFileEnding)
226 );
227 Load();
228 }
229
230
~emFileManTheme()231 emFileManTheme::~emFileManTheme()
232 {
233 }
234
235
236 //==============================================================================
237 //============================ emFileManThemeNames =============================
238 //==============================================================================
239
Acquire(emRootContext & rootContext)240 emRef<emFileManThemeNames> emFileManThemeNames::Acquire(
241 emRootContext & rootContext
242 )
243 {
244 EM_IMPL_ACQUIRE_COMMON(emFileManThemeNames,rootContext,"")
245 }
246
247
emFileManThemeNames(emContext & context,const emString & name)248 emFileManThemeNames::emFileManThemeNames(emContext & context, const emString & name)
249 : emModel(context,name)
250 {
251 emArray<emString> names;
252 int i, j, eLen, nLen;
253 emRef<emFileManTheme> t;
254 ThemeStyle * s;
255 ThemeAR * a;
256
257 try {
258 names=emTryLoadDir(emFileManTheme::GetThemesDirPath());
259 }
260 catch (const emException &) {
261 names.Clear();
262 }
263 eLen=strlen(emFileManTheme::ThemeFileEnding);
264 for (i=0; i<names.GetCount(); ) {
265 nLen=strlen(names[i])-eLen;
266 if (nLen>0 && strcmp(names[i].Get()+nLen,emFileManTheme::ThemeFileEnding)==0) {
267 names.GetWritable(i).Remove(nLen,eLen);
268 i++;
269 }
270 else {
271 names.Remove(i);
272 }
273 }
274 names.Sort(emStdComparer<emString>::Compare);
275
276 for (i=0; i<names.GetCount(); i++) {
277 t=emFileManTheme::Acquire(GetRootContext(),names[i]);
278 for (j=ThemeStyles.GetCount()-1; j>=0; j--) {
279 if (ThemeStyles[j].DisplayName==t->DisplayName.Get()) break;
280 }
281 if (j<0) {
282 j=ThemeStyles.GetCount();
283 ThemeStyles.AddNew();
284 }
285 s=&ThemeStyles.GetWritable(j);
286 s->DisplayName=t->DisplayName.Get();
287 s->DisplayIcon=t->DisplayIcon.Get();
288 for (j=0; j<s->ThemeARs.GetCount(); j++) {
289 if (s->ThemeARs[j].Height>t->Height.Get()) break;
290 }
291 s->ThemeARs.InsertNew(j);
292 a=&s->ThemeARs.GetWritable(j);
293 a->Name=names[i];
294 a->Height=t->Height.Get();
295 a->AspectRatio=HeightToAspectRatioString(a->Height);
296 t=NULL;
297 }
298
299 for (i=0; i<ThemeStyles.GetCount(); i++) {
300 for (j=0; j<ThemeStyles[i].ThemeARs.GetCount(); j++) {
301 NameToPackedIndex.Insert(
302 ThemeStyles[i].ThemeARs[j].Name,
303 (i<<16)|j
304 );
305 }
306 }
307
308 SetMinCommonLifetime(INT_MAX);
309 }
310
311
~emFileManThemeNames()312 emFileManThemeNames::~emFileManThemeNames()
313 {
314 }
315
316
GetThemeAspectRatioCount(int styleIndex) const317 int emFileManThemeNames::GetThemeAspectRatioCount(int styleIndex) const
318 {
319 if (styleIndex<0 || styleIndex>=ThemeStyles.GetCount()) {
320 return 0;
321 }
322 return ThemeStyles[styleIndex].ThemeARs.GetCount();
323 }
324
325
GetThemeName(int styleIndex,int aspectRatioIndex) const326 emString emFileManThemeNames::GetThemeName(
327 int styleIndex, int aspectRatioIndex
328 ) const
329 {
330 if (styleIndex<0 || styleIndex>=ThemeStyles.GetCount()) {
331 return emString();
332 }
333 const ThemeStyle & style=ThemeStyles[styleIndex];
334 if (aspectRatioIndex<0 || aspectRatioIndex>=style.ThemeARs.GetCount()) {
335 return emString();
336 }
337 return style.ThemeARs[aspectRatioIndex].Name;
338 }
339
340
GetDefaultThemeName() const341 emString emFileManThemeNames::GetDefaultThemeName() const
342 {
343 emString name;
344
345 name="Glass1";
346 if (!NameToPackedIndex.Contains(name)) {
347 name=GetThemeName(0,0);
348 }
349 return name;
350 }
351
352
GetThemeStyleDisplayName(int styleIndex) const353 emString emFileManThemeNames::GetThemeStyleDisplayName(
354 int styleIndex
355 ) const
356 {
357 if (styleIndex<0 || styleIndex>=ThemeStyles.GetCount()) {
358 return emString();
359 }
360 return ThemeStyles[styleIndex].DisplayName;
361 }
362
363
GetThemeStyleDisplayIcon(int styleIndex) const364 emString emFileManThemeNames::GetThemeStyleDisplayIcon(
365 int styleIndex
366 ) const
367 {
368 if (styleIndex<0 || styleIndex>=ThemeStyles.GetCount()) {
369 return emString();
370 }
371 return ThemeStyles[styleIndex].DisplayIcon;
372 }
373
374
GetThemeAspectRatio(int styleIndex,int aspectRatioIndex) const375 emString emFileManThemeNames::GetThemeAspectRatio(
376 int styleIndex, int aspectRatioIndex
377 ) const
378 {
379 if (styleIndex<0 || styleIndex>=ThemeStyles.GetCount()) {
380 return emString();
381 }
382 const ThemeStyle & style=ThemeStyles[styleIndex];
383 if (aspectRatioIndex<0 || aspectRatioIndex>=style.ThemeARs.GetCount()) {
384 return emString();
385 }
386 return style.ThemeARs[aspectRatioIndex].AspectRatio;
387 }
388
389
IsExistingThemeName(const emString & themeName) const390 bool emFileManThemeNames::IsExistingThemeName(const emString & themeName) const
391 {
392 return NameToPackedIndex.Contains(themeName);
393 }
394
395
GetThemeStyleIndex(const emString & themeName) const396 int emFileManThemeNames::GetThemeStyleIndex(
397 const emString & themeName
398 ) const
399 {
400 const emAvlTreeMap<emString,int>::Element * e;
401
402 e=NameToPackedIndex.Get(themeName);
403 if (!e) return -1;
404 return e->Value>>16;
405 }
406
407
GetThemeAspectRatioIndex(const emString & themeName) const408 int emFileManThemeNames::GetThemeAspectRatioIndex(
409 const emString & themeName
410 ) const
411 {
412 const emAvlTreeMap<emString,int>::Element * e;
413
414 e=NameToPackedIndex.Get(themeName);
415 if (!e) return -1;
416 return e->Value&0xFFFF;
417 }
418
419
HeightToAspectRatioString(double height)420 emString emFileManThemeNames::HeightToAspectRatioString(double height)
421 {
422 int n,d,bestN,bestD;
423
424 bestN=bestD=1;
425 for (d=1; d<=10; d++) {
426 n=(int)(d/height+0.5);
427 if (n<1) n=1;
428 if (fabs(height*n/d-1.0)<fabs(height*bestN/bestD-1.0)-0.001) {
429 bestN=n;
430 bestD=d;
431 }
432 }
433 return emString::Format("%d:%d",bestN,bestD);
434 }
435