1 (* coded by Ketmar // Invisible Vector <ketmar@ketmar.no-ip.org>
2 * Understanding is not required. Only obedience.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, version 3 of the License ONLY.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *)
16 {$INCLUDE ../shared/a_modes.inc}
17 {.$DEFINE UI_STYLE_DEBUG_SEARCH}
20 interface
22 uses
28 type
32 public
35 public
51 public
64 private
73 private
75 // "text-color#inactive@label"
78 public
84 public
90 private
94 private
101 public
109 public
118 // will return "default" (or raise an exception if there is no "default")
122 implementation
124 uses
125 fui_wadread;
128 var
132 {
133 function createDefaultStyle (): TUIStyle;
134 var
135 st: TStream;
136 begin
137 result := nil;
138 st := TStringStream.Create(defaultStyleStr);
139 st.position := 0;
140 try
141 result := TUIStyle.Create(st);
142 finally
143 FreeAndNil(st);
144 end;
145 end;
146 }
150 var
152 begin
154 begin
159 {
160 stl := createDefaultStyle();
161 SetLength(styles, Length(styles)+1);
162 styles[High(styles)] := stl;
163 result := stl;
164 }
169 var
171 begin
174 try
176 finally
183 var
187 begin
189 par := TFileTextParser.Create(st, false, [par.TOption.SignedNumbers, par.TOption.DollarIsId, par.TOption.DashIsId, par.TOption.HtmlColors]);
191 try
193 begin
196 //writeln('new style: <', stl.mId, '>');
198 while (f < Length(styles)) do begin if (strEquCI1251(styles[f].mId, stl.mId)) then break; Inc(f); end;
200 begin
202 end
203 else
204 begin
211 finally
215 // we should have "default" style
218 {
219 stl := createDefaultStyle();
220 SetLength(styles, Length(styles)+1);
221 styles[High(styles)] := stl;
222 }
226 // ////////////////////////////////////////////////////////////////////////// //
229 begin
237 constructor TStyleValue.Create (const v: AnsiString); begin vtype := TType.Str; sval := Pointer(v); end;
240 begin
249 begin
258 function TStyleValue.asRGBA: TGxRGBA; inline; begin if (vtype = TType.Color) then result := TGxRGBA.Create(r, g, b, a) else result := TGxRGBA.Create(0, 0, 0, 0); end;
259 function TStyleValue.asRGBADef (const def: TGxRGBA): TGxRGBA; inline; begin if (vtype = TType.Color) then result := TGxRGBA.Create(r, g, b, a) else result := def; end;
260 function TStyleValue.asInt (const def: Integer=0): Integer; inline; begin if (vtype = TType.Int) then result := ival else if (vtype = TType.Bool) then begin if (bval) then result := 1 else result := 0; end else result := def; end;
261 function TStyleValue.asBool (const def: Boolean=false): Boolean; inline; begin if (vtype = TType.Bool) then result := bval else if (vtype = TType.Int) then result := (ival <> 0) else result := def; end;
262 function TStyleValue.asStr (const def: AnsiString=''): AnsiString; inline; begin if (vtype = TType.Str) then result := AnsiString(sval) else result := def; end;
265 begin
270 TType.Color: if (a = 255) then result := formatstrf('rgb(%s,%s,%s)', [r, g, b]) else result := formatstrf('rgba(%s,%s,%s)', [r, g, b, a]);
276 // ////////////////////////////////////////////////////////////////////////// //
281 var
283 begin
290 // split
292 begin
293 // has ctl, and (possible) hash
295 begin
296 // has ctl and hash
298 begin
299 // @ctl#hash
305 end
306 else
307 begin
308 // #hash@ctl
315 end
316 else
317 begin
318 // has only ctl
323 end
325 begin
326 // has hash
330 end
331 else
332 begin
333 // only name
340 // ////////////////////////////////////////////////////////////////////////// //
342 begin
354 begin
367 begin
374 var
379 begin
383 // try control
386 begin
388 begin
389 // has ctl section?
393 // has hash?
395 begin
397 begin
401 // try name, go up with inheritance
403 begin
405 begin
408 // go up
410 begin
412 // for hash section: try parent section first
414 begin
415 {$IFDEF UI_STYLE_DEBUG_SEARCH}writeln('search for <#', hash, '@', ctl, '> at <#', sect.mHashName, '@', sect.mCtlName, '>: hash up');{$ENDIF}
418 {$IFDEF UI_STYLE_DEBUG_SEARCH}writeln(' hash up: trying <#', sect.mHashName, '@', sect.mCtlName, '>');{$ENDIF}
420 begin
423 // move another parent up
426 {$IFDEF UI_STYLE_DEBUG_SEARCH}writeln(' hash up: jumped up twice to <#', sect.mHashName, '@', sect.mCtlName, '>');{$ENDIF}
427 end
428 else
429 begin
430 // one parent up
431 {$IFDEF UI_STYLE_DEBUG_SEARCH}writeln('search for <#', hash, '@', ctl, '> at <#', sect.mHashName, '@', sect.mCtlName, '>: jump up');{$ENDIF}
435 // here, we should have non-hash section
437 // if we want hash, try to find it, otherwise do nothing
439 begin
440 {$IFDEF UI_STYLE_DEBUG_SEARCH}writeln(' search for <#', hash, '@', ctl, '> at <#', sect.mHashName, '@', sect.mCtlName, '>: hash down');{$ENDIF}
442 begin
444 {$IFDEF UI_STYLE_DEBUG_SEARCH}writeln(' found <#', sect.mHashName, '@', sect.mCtlName, '>');{$ENDIF}
447 end
448 else
449 begin
450 // inheritance
454 // parse inherit string
457 // find section
459 begin
460 // ctl
462 else if (strEquCI1251(ctl, '$up$')) then begin if (Length(sect.mHashName) <> 0) then sect := sect.mParent.mParent else sect := sect.mParent; end
466 begin
469 end
470 else
471 begin
472 // hash
474 // dummy loop, so i can use `break`
475 repeat
476 // get out of hash section
478 begin
479 {$IFDEF UI_STYLE_DEBUG_SEARCH}writeln('hash-jump-up: <#', sect.mHashName, '@', sect.mCtlName, '>');{$ENDIF}
482 // check for hash section in parent; use parent if there is no such hash section
483 {$IFDEF UI_STYLE_DEBUG_SEARCH}writeln(' checking parent: <#', sect.mHashName, '@', sect.mCtlName, '> for <#', hash, '>');{$ENDIF}
486 begin
488 begin
489 {$IFDEF UI_STYLE_DEBUG_SEARCH}writeln(' found in parent: <#', sect.mHashName, '@', sect.mCtlName, '> for <#', hash, '>');{$ENDIF}
493 end
494 else
495 begin
496 // we're in parent, try to find hash section
497 {$IFDEF UI_STYLE_DEBUG_SEARCH}writeln(' checking: <#', sect.mHashName, '@', sect.mCtlName, '> for <#', hash, '>');{$ENDIF}
499 begin
500 {$IFDEF UI_STYLE_DEBUG_SEARCH}writeln(' found: <#', sect.mHashName, '@', sect.mCtlName, '> for <#', hash, '>');{$ENDIF}
502 end
503 else
504 begin
505 // reuse current parent, but don't follow inheritance for it
514 // alas
519 // "text-color#inactive@label"
521 var
523 begin
526 //writeln('name:<', name, '>; hash:<', hash, '>; ctl:<', ctl, '>');
531 // ////////////////////////////////////////////////////////////////////////// //
533 begin
540 var
542 begin
546 par := TFileTextParser.Create(st, false, [par.TOption.SignedNumbers, par.TOption.DollarIsId, par.TOption.DashIsId, par.TOption.HtmlColors]);
547 try
549 finally
556 var
558 begin
560 try
562 finally
569 begin
576 begin
583 begin
588 begin
595 begin
603 var
609 begin
612 begin
615 begin
620 begin
629 begin
635 begin
640 begin
642 // ctl
644 begin
649 begin
650 // create new section
657 end
658 else
659 begin
667 continue;
669 // hash
671 begin
676 begin
677 // create new section
684 end
685 else
686 begin
694 continue;
696 // name
700 begin
701 // color
708 begin
710 end
711 else
712 begin
716 end
718 begin
719 // html color
721 //writeln('<', par.tokStr, '>; {', par.curChar, '}');
724 begin
725 // #rgb
729 end
730 else
731 begin
732 // #rrggbb
738 //writeln(' r=', v.r, '; g=', v.g, '; b=', v.b);
740 end
742 begin
745 end
747 begin
750 end
752 begin
753 // string value
756 end
758 begin
760 end
761 else
762 begin
763 // should be int
773 begin
774 // style name
776 begin
778 end
779 else
780 begin