Phil in the Mirror๋ผ๋Š” ๊ฒŒ์ž„ 1์ธ ๊ฐœ๋ฐœ ํ–ˆ๊ณ 

์ซ„๋”ฑ ๋งํ•œ ๋’ค ๋‚ด๊ฐ€ ํ–ˆ๋˜ ์ž‘์—…๋“ค ๊ฐ„๋‹จํ•˜๊ฒŒ ์ •๋ฆฌํ•˜๊ณ  ์žˆ์–ด์„œ ๋‚ด์šฉ์„ ์—ฌ๊ธฐ์—๋„ ๊ณต์œ ํ•˜๋ ค๊ณ  ํ•ด.

๊ธฐ์ˆ ์ ์ธ ๋‚ด์šฉ๋“ค ์œ„์ฃผ๋กœ ์ž‘์„ฑ๋  ๊ฑฐ๋ผ, ์–ธ๋ฆฌ์–ผ ์—”์ง„์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒŒ์ด๋“คํ•œํ…Œ๋Š” ๋ณ„๋กœ ๋„์›€์€ ์•ˆ ๋  ๋“ฏ.


์ด๋ฒˆ ๋‚ด์šฉ์€ ์–ธ๋ฆฌ์–ผ ์—”์ง„์—์„œ ๋‚ด๊ฐ€ ์›ํ•˜๋Š” UI์˜ ํ˜•ํƒœ๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด์„œ

์œ ์ € ์œ„์ ฏ ๋ธ”๋ฃจํ”„๋ฆฐํŠธ๊ฐ€ ์•„๋‹Œ C++ ์ฝ”๋”ฉ์„ ํ†ตํ•ด ์ปค์Šคํ…€ ์Šฌ๋ ˆ์ดํŠธ ์œ„์ ฏ์„ ๋งŒ๋“ค๊ณ  ํ™œ์šฉํ•œ ์‚ฌ๋ก€์•ผ.

์ž์„ธํžˆ ์„ค๋ช…ํ•˜๋ ค๊ณ  ๋…ธ๋ ฅํ•˜๋‹ค ๋ณด๋‹ˆ ์ฝ”๋“œ๊ฐ€ ๋งŽ์•„์„œ ์ฝ๊ธฐ ์–ด๋ ค์šธ ์ˆ˜๋„.. ์ดํ•ด์ข€


๊ธ€๊ณ  ๋ชจ๋ฐ”์ผ์—์„œ๋Š” ์ฝ”๋“œ๊ฐ€ ์ œ๋Œ€๋กœ ์•ˆ ๋ณด์ด๋„ค. ์ด๊ฑฐ ๊ด€๋ จํ•ด์„œ ๋ชจ๋ฐ”์ผ๋„ ์ž˜ ๋ณด์ผ๋งŒํ•œ ์ฝ”๋“œ html ํฌ๋งคํ„ฐ ์ถ”์ฒœํ•ด์ค„ ์ธ๋ถ•์ด ์žˆ์Œ ๋Œ“๊ธ€์ข€

์ผ๋‹จ carbon์œผ๋กœ ๋Œ€์ฒดํ•ด์„œ ์˜ฌ๋ฆผ


===============================================


Custom Slate Widget


ย  Phil in the Mirror์—์„œ๋Š” ์–ธ๋ฆฌ์–ผ ์—”์ง„ 5์—์„œ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ œ๊ณตํ•˜์ง€ ์•Š๋Š” UI ์š”์†Œ ๋ช‡๋ช‡๊ฐ€์ง€๊ฐ€ ํ•„์š”ํ–ˆ๋Š”๋ฐ์š”. ๊ทธ๋Ÿฌํ•œ ์š”์†Œ๋“ค์„ ์–ด๋–ป๊ฒŒ ๋งŒ๋“ค์–ด์„œ ํ•ด๊ฒฐํ–ˆ๋Š”์ง€์— ๋Œ€ํ•ด์„œ ๊ธฐ์ˆ ํ•ด๋ณผ๊นŒ ํ•ฉ๋‹ˆ๋‹ค. ๋‹จ์ˆœํžˆ ์œ ์ € ์œ„์ ฏ ๋ธ”๋ฃจํ”„๋ฆฐํŠธ๋ฅผ ์ด์šฉํ•œ ์—๋””ํ„ฐ ์ˆ˜์ค€์—์„œ ํ•ด๊ฒฐํ•  ์ˆ˜๋„ ์žˆ์—ˆ์ง€๋งŒ ์ฝ”๋“œ ์ˆ˜์ค€์—์„œ ์ด๋“ค์„ ์ ์ ˆํžˆ ๊ตฌํ˜„ํ•ด์„œ, ์œ ์—ฐํ•จ๊ณผ ์„ฑ๋Šฅ์  ์ด์  ๋ฐ ์‚ฌ์šฉ์„ฑ์„ ์ฑ™๊ธด ์‚ฌ๋ก€๋ฅผ ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค.



1) Redact Decorator


ย  Phil in the Mirror์—์„œ ํ”Œ๋ ˆ์ด์–ด๋Š” ๋‹ค์–‘ํ•œ ๋ฌธ์„œ๋“ค์„ ์ฝ๊ณ  ์‚ฌ๊ฑด๋“ค์˜ ๊ด€๊ณ„๋ฅผ ํŒŒ์•…ํ•˜์—ฌ ์ˆจ๊ฒจ์ง„ ๋‚ ์งœ๋“ค์„ ์ถ”๋ฆฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ค‘์š”ํ•œ ์ •๋ณด๋“ค์€ ๊ฐ€๋ ค๋†“๊ณ , ์ด๋“ค์„ ์ถ”๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋งŒ ์—ฌ๊ธฐ์„œ ๊ณ ๋ ค๋˜์–ด์•ผ ํ•  ์‚ฌํ•ญ์ด ์žˆ์—ˆ๋Š”๋ฐ์š”. ๋ฐ”๋กœ ๋กœ์ปฌ๋ผ์ด์ œ์ด์…˜์ž…๋‹ˆ๋‹ค. ํ…์ŠคํŠธ ์ƒ์—์„œ ๊ฐ€๋ ค์งˆ ๋ถ€๋ถ„๋“ค์€ ์–ด๋–ค ์–ธ์–ด์ด๋А๋ƒ์— ๋”ฐ๋ผ์„œ ์œ„์น˜๊ฐ€ ๋‹ฌ๋ผ์ง€๊ณ , ๊ธธ์ด๋„ ๋‹ฌ๋ผ์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ํ•ด๊ฒฐํ•  ํ•„์š”๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.


ํ…์ŠคํŠธ์˜ ์ผ๋ถ€๊ฐ€ ๊ฒ€์ •์ƒ‰์œผ๋กœ ๊ฐ€๋ ค์ ธ ์žˆ์Šต๋‹ˆ๋‹ค.

ย  ๋‹จ์ˆœํžˆ U+2588(โ–ˆ) ๋ฌธ์ž๋ฅผ ์ด์šฉํ•  ์ˆ˜๋„ ์žˆ์—ˆ์ง€๋งŒ, ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค: 1) ์–ธ์–ด๋งˆ๋‹ค ๊ธ€์ž์˜ ๊ฐœ์ˆ˜๊ฐ€ ์ƒ์ดํ•œ๋ฐ, ์ •๋ง๋กœ ๋ฌธ๋งฅ ์ƒ์˜ ๋‹จ์–ด๊ฐ€ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๊ฐ€๋ ค์ง€๋Š” ๋А๋‚Œ์„ ์—ฐ์ถœํ•˜๊ธฐ ์–ด๋ ค์› ์Šต๋‹ˆ๋‹ค. ๊ฐ€๋ น "์†๊ฐ€๋ฝ ์ ˆ๋‹จ ์‚ฌ๊ณ "์™€ "finger amputation accident"๋Š” ๊ธ€์ž์ˆ˜์˜ ์ฐจ์ด๊ฐ€ ์ปค์„œ, ์–ด๋А ํ•œ์ชฝ ์–ธ์–ด์—์„œ ์–ด์ƒ‰ํ•˜๊ฒŒ ๋ณด์ด๋Š” ์ธก๋ฉด์ด ์žˆ์Šต๋‹ˆ๋‹ค. 2) ์‚ฌ์ด์— ๊ณต๋ฐฑ์ด ์—†์ด ์ด์–ด์ง€๋Š” ๋А๋‚Œ์ด ํ•„์š”ํ–ˆ์Šต๋‹ˆ๋‹ค. (โ–ˆโ–ˆโ–ˆ์ฒ˜๋Ÿผ ์ด์–ด์„œ ์จ๋ณด๋ฉด ์‚ฌ์ด์— ์• ๋งคํ•œ ๊ณต๋ฐฑ์ด ๋ณด์ž…๋‹ˆ๋‹ค)


ย  ๋”ฐ๋ผ์„œ ํ…์ŠคํŠธ๊ฐ€ ๋ Œ๋”๋ง๋  ๋•Œ, ํ•ด๋‹น ์˜์—ญ ์œ„์— ๊ฒ€์ •์ƒ‰ ๋ฐ•์Šค๋ฅผ ๊ทธ๋ ค๋‚ผ ํ•„์š”๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” RichTextBlock์˜ ๊ธฐ๋Šฅ์„ ํ™•์žฅํ•˜์—ฌ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์ •ํ™•ํžˆ๋Š”, Decorator๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด์ฃ . RichTextBlock์€ Decorator๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ด๋Ÿฌํ•œ Decorator๋“ค์€ RichTextBlock์˜ ๋‚ด์šฉ์— ์ ‘๊ทผํ•˜์—ฌ ๋ณธ์ธ์ด ๊พธ๋ฐ€ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ๋“ค์„ ๊พธ๋ฏธ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ €๋Š” "<redact>content</>" ๋”ฐ์œ„๋กœ ๊ฐ์‹ธ์ ธ์žˆ๋Š” ๋‚ด์šฉ์„ RedactDecorator๊ฐ€ ์ ‘๊ทผํ•˜์—ฌ ๊ฒ€์ •์ƒ‰ ๋ฐ•์Šค๋ฅผ ๊ทธ๋ ค๋‚ด๋Š” ํ˜•ํƒœ๋กœ ๊ตฌํ˜„ํ•˜์˜€์Šต๋‹ˆ๋‹ค.



์œ„์ ฏ์„ ์ด์šฉํ•œ ๊ฐ€๋ฆฌ๊ธฐ


ย  ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์„ ๊ณ ๋ คํ•  ์ˆ˜ ์žˆ์—ˆ๋Š”๋ฐ์š”. ์ฒซ ๋ฒˆ์งธ๋Š” ํ•ด๋‹น ์œ„์น˜์— SBox ์œ„์ ฏ์„ ์ ์ ˆํžˆ ์ƒ์„ฑํ•ด์„œ ๊ฐ€๋ฆฌ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ์ œ๊ฐ€ ์ฒ˜์Œ์œผ๋กœ ์ ‘๊ทผํ•œ ๋ฐฉ๋ฒ•์ด์—ˆ์Šต๋‹ˆ๋‹ค. ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:



2ebcc224eadc78ee3ff698a518d604038f7f1cf897b5b8b02e26ad



ย  RichTextBlock์—์„œ ํ…์ŠคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•  ๋•Œ, Run์ด๋ผ๋Š” ๋‹จ์œ„๋กœ ๋‚˜๋ˆ„์–ด์„œ ํ…์ŠคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ํ…์ŠคํŠธ์˜ ๊ธธ์ด๊ฐ€ ๊ธธ๋‹ค๊ฑฐ๋‚˜ ํ•ด์„œ ์ค„๋ฐ”๊ฟˆ ๋“ฑ์ด ์ผ์–ด๋‚  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ์ด๋Ÿฌํ•œ ๊ฒƒ๋“ค๋กœ๋ถ€ํ„ฐ ์ž์œ ๋กœ์šด ์ตœ์†Œํ•œ์˜ ๋ Œ๋” ๋‹จ์œ„๋ฅผ ๊ฐ–๋Š” ๊ฒƒ์ด์ฃ (์˜ˆ๋ฅผ ๋“ค๋ฉด, ๋‹จ์–ด ํ•˜๋‚˜). Supports()๋Š” ํ•ด๋‹น Decorator๊ฐ€ ์–ด๋–ค ํ…์ŠคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ• ์ง€๋ฅผ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค. Create()์—์„œ๋Š” Supports()์—์„œ true๋ฅผ ๋ฐ˜ํ™˜ํ•œ Run์ด ์ธ์ž๋กœ ๋„˜์–ด์˜ค๊ฒŒ ๋˜๊ณ , Decorator ํด๋ž˜์Šค๋“ค์€ ์ฃผ์–ด์ง„ Run๋“ค์— ๋Œ€ํ•ด์„œ ์ถ”๊ฐ€์ ์ธ ํ–‰์œ„๋ฅผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.ย 


ย  Run ์ •๋ณด๋ฅผ ์ด์šฉํ•ด์„œ, ์–ด๋–ค TextStyle์„ ์ ์šฉํ•ด์•ผ ํ• ์ง€ ๊ฒฐ์ •ํ•˜๊ณ , FontMeasure๋ฅผ ์ด์šฉํ•ด์„œ ํ•ด๋‹น Run์ด ์–ด๋А์ •๋„์˜ ํฌ๊ธฐ๋ฅผ ๊ฐ–๊ณ  ์–ด๋А ์œ„์น˜์— ๋ Œ๋”๋ง๋ ์ง€ ๊ณ„์‚ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ์ด์šฉํ•ด์„œ ๊ฒ€์ •์ƒ‰์˜ Border๋ฅผ ์ž์‹์œผ๋กœ ๊ฐ–๋Š” SBox ์œ„์ ฏ์„ ์ƒ์„ฑํ•˜์—ฌ ํ•ด๋‹น ํ…์ŠคํŠธ๋ฅผ ๊ฐ€๋ฆฌ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.ย 


ย  ํ•˜์ง€๋งŒ ์ด๋Š” ์–ด์จŒ๊ฑฐ๋‚˜ ์ƒˆ๋กœ์šด ์œ„์ ฏ์„ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์—, ์•ฝ๊ฐ„์˜ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์• ์ดˆ์— FSlateTextRun์—์„œ 'ํ…์ŠคํŠธ๋ฅผ ๋ Œ๋”๋ง'ํ•˜๋Š” ๊ณผ์ •์„ ๊ฑฐ์น˜๋ฏ€๋กœ, FSlateTextRun์„ ํ™•์žฅํ•˜์—ฌ 'ํ…์ŠคํŠธ๋ฅผ ๋ Œ๋”๋งํ•˜์ง€ ์•Š๊ณ  ๊ฒ€์ •์ƒ‰ ๋ฐ•์Šค๋ฅผ ๋ Œ๋”๋ง'ํ•˜๊ฒŒ๋” ํ•˜๋ฉด ๋” ๊ฐ„๊ฒฐํ•œ ๊ตฌํ˜„์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.


ย  ๊ธฐ์กด์˜ RedactDecorator๋Š” ๊ฐ€๋ ค์ ธ์•ผ ํ•  ํ…์ŠคํŠธ์˜ Run์— ๋Œ€ํ•ด FSlateWidgetRun์„ ๋ฐ˜ํ™˜ํ•˜๊ณ , ํ•ด๋‹น ์œ„์ ฏ์— ํ…์ŠคํŠธ์™€ ๋ฐ•์Šค๋ฅผ ๋„ฃ์—ˆ์Šต๋‹ˆ๋‹ค. ๋Œ€์‹ ์—, FRedactTextRun์„ ๋งŒ๋“ค์–ด์„œ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ํ•˜๊ณ , FRedactTextRun์€ ๊ธ€์ž์™€ ๊ด€๊ณ„์—†์ด ๊ทธ ํฌ๊ธฐ๋งŒํผ ๋‹จ์ˆœํžˆ ๊ฒ€์ •์ƒ‰ ์ƒ์ž๋ฅผ ๋ Œ๋”๋งํ•˜๋„๋ก ๊ฐœ์„ ํ•˜๋ฉด, ํ…์ŠคํŠธ๋ฅผ ๋ Œ๋”๋งํ•˜๋Š”๊ฒƒ๊ณผ ๋ณตํ•ฉ ์œ„์ ฏ์„ ๋ Œ๋”๋งํ•˜๋Š” ์˜ค๋ฒ„ํ—ค๋“œ ๋“ฑ์„ ์—†์•จ ์ˆ˜ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค:



2ebcc224eadc78ee3cf698a518d60403d9a7bf94f0fa93122b1e



ย  RedactDecorator๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์•„์งˆ ๊ฒƒ์ž…๋‹ˆ๋‹ค:



2ebcc224eadc78ee3df698a518d6040300ecda6493c5cb10edaf



ย  ์ด๋Ÿฐ ์‹์˜ ๊ตฌํ˜„์€ "<redact>์•„์ฃผ ๊ธด ๋ฌธ์žฅ์œผ๋กœ ์ด๋ฃจ์–ด์ง„ ํ…์ŠคํŠธ</>" ๋”ฐ์œ„์ฒ˜๋Ÿผ ๊ตฌ์„ฑ๋œ ์ƒํ™ฉ์—์„œ๋„ ์ด์ ์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด, SBox๋ฅผ ์ง์ ‘ ๊ตฌ์„ฑํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” ์–ด์จŒ๊ฑฐ๋‚˜ ํ•˜๋‚˜์˜ SlateWidgetRun์œผ๋กœ ๊ตฌ์„ฑ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์—ฌ๋Ÿฌ ๋‹จ์–ด๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์Œ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ์ค„๋ฐ”๊ฟˆ์ด ์ด๋ฃจ์–ด์ง€์ง€ ์•Š์•˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ FRedactTextRun์€ FSlateTextRun์„ ์ƒ์†๋ฐ›๊ธฐ ๋•Œ๋ฌธ์—, ๋‚ด๋ถ€์ ์œผ๋กœ ๋‹จ์–ด ๋ณ„ wrapping์ด ์ด๋ฃจ์–ด์ง€๊ณ  ์ด์— ๋Œ€ํ•œ ์ด์ ์„ ์–ป์„ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ์ฒ˜๋Ÿผ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์ค„๋ฐ”๊ฟˆ์ด ์ด๋ฃจ์–ด์ง€๋Š” ๊ฒƒ์„ ํ™•์ธํ•˜์„ธ์š”:


์•„์ฃผ ๊ธด ๊ฒ€์—ด ์ƒ์ž์˜ ๊ฒฝ์šฐ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์ค„๋ฐ”๊ฟˆ์ด ์ด๋ฃจ์–ด์ง‘๋‹ˆ๋‹ค.


2)ย  Fixed Size Thumb Scroll


ย  Phil in the Mirror์—์„œ๋Š” ๋ฌธ์„œ๋ฅผ ์Šคํฌ๋กคํ•˜๋ฉด์„œ ์ฝ์„ ์ˆ˜ ์žˆ์–ด์•ผ ํ–ˆ๋Š”๋ฐ์š”. ์ €๋Š” ์Šคํฌ๋กค์˜ ์œ„์น˜๋ฅผ ํ‘œ์‹œํ•˜๋Š” ๋ง‰๋Œ€(thumb)๊ฐ€ ์•„์ฃผ ์ž‘๊ณ  ๊ณ ์ •๋œ ํฌ๊ธฐ์˜€์œผ๋ฉด ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์–ธ๋ฆฌ์–ผ ์—”์ง„์—์„œ ์ œ๊ณตํ•˜๋Š” ์Šคํฌ๋กค ์œ„์ ฏ์—์„œ๋Š” ๋ง‰๋Œ€์˜ ํฌ๊ธฐ๋ฅผ ์กฐ์ ˆํ•  ์ˆ˜ ์žˆ๋Š” ์˜ต์…˜์ด ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ด๋Ÿฌํ•œ UI๋ฅผ ๋ณ„๋„๋กœ ๋งŒ๋“ค์–ด์ค„ ํ•„์š”๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.


์šฐ์ธก ์ธ๋””์ผ€์ดํ„ฐ์—์„œ ํ•˜์–€์ƒ‰ ์ƒ์ž๊ฐ™์ด ์ž‘์€ ์Šคํฌ๋กค ๋ง‰๋Œ€๋ฅผ ์›ํ–ˆ์Šต๋‹ˆ๋‹ค.


ย  ์šฐ์„  ์ปค์Šคํ…€ ์Šฌ๋ ˆ์ดํŠธ ์œ„์ ฏ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ๊ณ ๋ คํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค: 1) ์–ธ๋ฆฌ์–ผ ์—”์ง„์˜ ๊ธฐ๋ณธ ์Šคํฌ๋กค ๋ฐ”๋ฅผ ์ˆจ๊ธด ๋’ค 2) ์ œ๊ฐ€ ์›ํ•˜๋Š” ํ˜•ํƒœ์˜ ์Šคํฌ๋กค ๋ฐ” ํ˜•ํƒœ์˜ ์œ„์ ฏ๋“ค์„ ์ž˜ ์กฐํ•ฉํ•ด์„œ ๋ฐฐ์น˜ํ•˜๊ณ  3) ์Šคํฌ๋กค์˜ ๋ณ€ํ™”๋ฅผ ๋ฐ›๋Š” ๋ฆฌ์Šค๋„ˆ๋ฅผ ๋งŒ๋“ค์–ด ํ•ด๋‹น ์œ„์น˜์— ๋”ฐ๋ผ ๋ง‰๋Œ€ ์œ„์น˜๋ฅผ ์ง์ ‘ ์กฐ์ ˆํ•ด์ฃผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ฌผ๋ก  ์ด๋ ‡๊ฒŒ ํ•ด๋„ ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์Šคํฌ๋กค ์œ„์ ฏ๊ณผ ์ธ๋””์ผ€์ดํ„ฐ๋ฅผ ์œ„์ ฏ ๋ธ”๋ฃจํ”„๋ฆฐํŠธ๋ฅผ ์ด์šฉํ•ด ํ—ˆ์ˆ ํ•˜๊ฒŒ ๋ฌถ๋Š” ๊ฒƒ์ด ์•ฝ๊ฐ„์€ ๊ฑฑ์ •์ด ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ €๋Š” ์–ธ๋ฆฌ์–ผ ์—”์ง„ ๊ฒฝํ—˜๋„ ๋ถ€์กฑํ–ˆ๊ณ , ์ฐจํ›„ ์–ด๋–ป๊ฒŒ ๋ณ€๊ฒฝ๋  ์ง€ ๋ชฐ๋ž๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.


ย  ๋”ฐ๋ผ์„œ ์Šคํฌ๋กค ์œ„์ ฏ๊ณผ ๋™์ผํ•˜์ง€๋งŒ ๊ณ ์ •๋œ ๋ง‰๋Œ€ ๊ธธ์ด๋ฅผ ๊ฐ–๋Š” ์ปค์Šคํ…€ ์Šฌ๋ ˆ์ดํŠธ ์œ„์ ฏ์„ ๋งŒ๋“ค์–ด ํ•ด๊ฒฐํ•˜๊ธฐ๋กœ ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์šฐ์„ , FixedThumbScrollBox๋ผ๋Š” ์œ„์ ฏ์„ ๋งŒ๋“ค์–ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๋ณ„๋‹ค๋ฅธ ์ž‘์—…์€ ์•„๋‹ˆ๊ณ , ๊ทธ๋ƒฅ ์œ„์ ฏ ๋ธ”๋ฃจํ”„๋ฆฐํŠธ๋ฅผ ์ด์šฉํ•˜๋˜ ๊ฒƒ์„ C++ ์ˆ˜์ค€์œผ๋กœ ์˜ฎ๊ฒจ๋†“์€ ๊ฒƒ์— ๊ฐ€๊น์Šต๋‹ˆ๋‹ค. UFixedThumbScrollBox๋Š” ๋‹จ์ˆœํžˆ ์•ˆ์ชฝ์— SScrollBox๋ฅผ ๋งŒ๋“ค๊ณ , ์˜†์— ๊ฐ์ข… ๋ฒ„ํŠผ๊ณผ FixedThumbScrollBar๊ฐ€ ๋ฐฐ์น˜๋˜๋Š” ๋ณตํ•ฉ ์œ„์ ฏ์ž…๋‹ˆ๋‹ค.


๋Œ€๋žต์ ์ธ ์œ„์ ฏ์˜ ๊ตฌ์„ฑ. ์ตœ์ƒ์œ„์—๋Š” HorizontalBox๊ฐ€, ๊ทธ ํ•˜์œ„์—๋Š” ScrollBox์™€ VerticalBox, VerticalBox ํ•˜์œ„์—๋Š” UpButton๊ณผ FixedThumbScrollBar, DownButton์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.


ย  ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:


2ebcc224eadc78ee3af698a518d604038d993355469b6e96cd8ac9


ย  ์—ฌ๊ธฐ์„œ ํ•ต์‹ฌ์€ SScrollBox๋ฅผ ๋ฐฐ์น˜ํ•œ ๋’ค, SScrollBox์˜ ๋ณ€ํ™”๋ฅผ ์ถ”์ ํ•˜๋Š” ์ปค์Šคํ…€ ScrollBar๋ฅผ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋Š” SFixedThumbScrollBar๋กœ ๊ตฌํ˜„๋˜์—ˆ์œผ๋ฉฐ, SScrollBar๋ฅผ ์ƒ์†๋ฐ›์Šต๋‹ˆ๋‹ค. ๋‹คํ–‰ํžˆ, SScrollBox์—๋Š” ExternalScrollBar๋ผ๋Š” ์ธ์ˆ˜๊ฐ€ ์žˆ์–ด ์ด๋ฅผ ์ด์šฉํ•˜์—ฌ ์™ธ์žฅ ์Šคํฌ๋กค ๋ง‰๋Œ€๋ฅผ ์†์‰ฝ๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.ย 


ย  SFixedThumbScrollBar์—์„œ๋Š” ํฐ ๊ตฌํ˜„์˜ ๋ณ€ํ™”๊ฐ€ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ๋‹จ์ˆœํžˆ ๊ทธ๋ฆฌ๋Š” ๋ฐฉ์‹๋งŒ ๋ณ€๊ฒฝํ•˜๋ฉด ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์ด์ฃ . ๋”ฐ๋ผ์„œ 1) FixedThumbSize๋ฅผ ์ œ์™ธํ•œ ๋ชจ๋“  ๋ฉค๋ฒ„๋“ค์€ ๋ถ€๋ชจ์˜ ์ดˆ๊ธฐํ™”๋ฅผ ๋”ฐ๋ผ๊ฐ€๊ณ , 2) OnPaint์—์„œ MakeBox๋ฅผ ์ด์šฉํ•ด ์ ์ ˆํ•œ ์œ„์น˜์— ๋ง‰๋Œ€๋ฅผ ๊ทธ๋ ค์ฃผ๊ธฐ๋งŒ ํ•˜๋ฉด ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”:



2ebcc224eadc78ee3bf698a518d604032075e40b2d2df2cf4e32fd




ย  ์ €๋Š” Vertical๋กœ๋งŒ ์ œ๋Œ€๋กœ ๋™์ž‘ํ•˜๋ฉด ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์—, Horizontal ๋ฐฉํ–ฅ์— ๋Œ€ํ•ด์„œ ๋ณ„๋„์˜ ํ…Œ์ŠคํŠธ๋ฅผ ๊ฑฐ์น˜์ง€๋Š” ์•Š์•˜์Šต๋‹ˆ๋‹ค. ํ•˜์—ฌํŠผ, ๋ง‰๋Œ€์˜ ์œ„์น˜๋Š” ์Šคํฌ๋กค์˜ ์ƒ๋Œ€์ ์ธ ์œ„์น˜(0์ด๋ฉด ๋งจ ์œ„, 1์ด๋ฉด ๋งจ ์•„๋ž˜)๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ค‘์•™์ ์„ ์žก์œผ๋ฉด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ฝ”๋“œ์—์„œ๋Š” ThumbTop์„ ๊ณ„์‚ฐํ•ด์•ผ ํ–ˆ์œผ๋ฏ€๋กœ, ๋ง‰๋Œ€์˜ ์ „์ฒด ๊ธธ์ด์—์„œ FixedThumbSize๋งŒํผ์„ ๋บ€ ๋’ค์— ์ƒ๋Œ€์ ์ธ ์œ„์น˜๋ฅผ ์ ์šฉํ•˜์˜€์Œ์— ์œ ์˜ํ•˜์„ธ์š”.


ย  ๊ฒฐ๊ณผ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๊ณ ์ •๋œ ๊ธธ์ด์˜ ์ž‘์€ ๋ง‰๋Œ€๊ฐ€ ์Šคํฌ๋กค์˜ ์œ„์น˜์— ๋”ฐ๋ผ ์ ์ ˆํžˆ ๋ณ€ํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:




3) Grid Table Decorator


ย  ์–ธ๋ฆฌ์–ผ ์—”์ง„์—์„œ๋Š” ๊ฒฉ์ž์˜ ํ˜•ํƒœ๋กœ ๋ ˆ์ด์•„์›ƒ์„ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๋Š” GridPanel์„ ์ œ๊ณตํ•˜๋Š”๋ฐ์š”. ์ €๋Š” ๋ฌธ์„œ๋“ค์„ ์—ฐ์ถœํ•ด์•ผ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์—, ์ด๋ฅผ ์ด์šฉํ•ด์„œ ํ‘œ ๋“ฑ์„ ์‰ฝ๊ฒŒ ๊ทธ๋ ค๋‚ด๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค. ํ‘œ ๋ ˆ์ด์•„์›ƒ ๋””์ž์ธ์„ ๋ณ„๋„๋กœ ๋งŒ๋“  ๋’ค ์ด๋ฏธ์ง€๋ฅผ ์‚ฝ์ž…ํ•˜๊ณ , ๊ฐ ์œ„์น˜์— TextBlock์„ ๋ฐฐ์น˜ํ•˜๋Š” ๊ฒƒ์€ ์œ ์—ฐํ•˜์ง€ ์•Š๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ํ•œ ํ–‰์„ ๋” ์ถ”๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ํ•  ๋•Œ, ํ‘œ ๋ ˆ์ด์•„์›ƒ ์ด๋ฏธ์ง€๋ฅผ ๋‹ค์‹œ ๊ทธ๋ ค์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด์ฃ . ๋˜ํ•œ, ๋กœ์ปฌ๋ผ์ด์ œ์ด์…˜์„ ๊ณ ๋ คํ•ด TextBlock์˜ ์‚ฌ์ด์ฆˆ์—๋„ ๋งŽ์€ ์‹ ๊ฒฝ์„ ์จ์•ผํ–ˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ ˆ์ฐจ์ ์ธ ๋””์ž์ธ์ด ํ•„์š”ํ•œ ์ˆœ๊ฐ„์ด์—ˆ์ฃ .


ย  ํŠนํžˆ, GridPanel์„ ์‚ฌ์šฉํ•˜๋ฉด์„œ๋„ ๋ช‡๋ช‡๊ฐ€์ง€ ๋””์ž์ธ ์š”๊ตฌ์‚ฌํ•ญ์„ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ฐ ํ‘œ ํ•ญ๋ชฉ์„ ๊ตฌ๋ถ„ํ•˜๋Š” ๊ฒฝ๊ณ„์„ ์„ ๊ทธ๋ฆด ์ˆ˜ ์žˆ์–ด์•ผ ํ–ˆ๊ณ , ํŠน์ • ํ–‰ ๋‹ค์Œ์—๋Š” ๊ตฌ๋ถ„์„ ์„ ๊ทธ๋ฆด ์ˆ˜๋„ ์žˆ์–ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์™ธ๊ณฝ์„ ์€ ๊ทธ๋ฆฌ์ง€ ์•Š๊ณ  ๋‚ด๋ถ€์„ ๋งŒ ๊ทธ๋ฆด ์ˆ˜๋„ ์žˆ์–ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ ๊ทธ๋ฆผ์„ ์ฐธ๊ณ ํ•˜์„ธ์š”:


ํ—ค๋” ๋‹ค์Œ์˜ ํ–‰์€ ๊ตต์€ ์„ ์œผ๋กœ ๊ทธ๋ ค์ ธ์žˆ๊ณ , ํ‘œ์˜ ์™ธ๊ณฝ์„ ์€ ๊ทธ๋ ค์ ธ์žˆ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.


ย  ์ ˆ์ฐจ์ ์ธ ๋””์ž์ธ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์€, GridPanel ์•ˆ์— ๋‹ค์‹œ Border๋ฅผ ๋งŒ๋“ค๊ณ  Border ์•ˆ์— TextBlock์„ ์‚ฝ์ž…ํ•œ ๋’ค Border๋ฅผ ์ด์šฉํ•ด์„œ ๊ฐ ์„ ์˜ ๋””์ž์ธ์„ ํ•ด๊ฒฐํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋Š” ํ‘œ์˜ ๋ชจ๋“  ์นธ์—๋‹ค๊ฐ€ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•˜๋Š” ์ž‘์—…๋“ค์ด๊ณ , ๊ตฌ๋ถ„์„ ์„ ๊ทธ๋ฆฐ๋‹ค๊ฑฐ๋‚˜ ์™ธ๊ณฝ์„ ์„ ๊ทธ๋ฆฌ์ง€ ์•Š๋Š” ๋“ฑ์˜ ๋””์ž์ธ์„ ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์กฐ๊ธˆ ๋” ๋ณต์žกํ•œ ์ž‘์—…์ด ์š”๊ตฌ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ด๋Ÿฐ ๋ฐฉ๋ฒ• ๋Œ€์‹ , GridTableDecorator๋ผ๋Š” ์œ„์ ฏ์„ ๋งŒ๋“ค์–ด ์š”๊ตฌ์‚ฌํ•ญ์— ๋งž๊ฒŒ ํ‘œ๋ฅผ ๊พธ๋ฉฐ์ฃผ๋„๋ก ํ–ˆ์Šต๋‹ˆ๋‹ค.


GridTableDecorator ํ•˜์œ„์˜ GridTable์€ GridTableDecorator์— ์˜ํ•ด์„œ ๊พธ๋ฉฐ์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.


ย  ๊ธฐ๋ณธ์ ์ธ ์ „๋žต์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค: GridTableDecorator์˜ ์ž์‹์œผ๋กœ GridTable์„ ๋†“์œผ๋ฉด, GridTableDecorator๋Š” ํ•ด๋‹น GridTable์„ ์ž์‹ ์˜ ์†์„ฑ์— ๋”ฐ๋ผ ์ ์ ˆํžˆ ๊พธ๋ฐ‰๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด์„œ๋Š”ย  GridPanel์˜ ์†์„ฑ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ฒฝ๊ณ„์„ ์ด ์–ด๋””์— ์œ„์น˜ํ•ด์•ผ ํ•˜๋Š”์ง€ ๊ณ„์‚ฐํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋งŒ ์ €๋Š” Span ๊ด€๋ จ ์†์„ฑ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•˜์œผ๋ฏ€๋กœ, ์ด์™€ ๊ด€ํ•œ ๊ณ ๋ ค๋Š” ์ •ํ™•ํ•œ ํ…Œ์ŠคํŠธ๋ฅผ ๊ฑฐ์น˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”:


2ebcc224eadc78ee38f698a518d6040311a9efaf237aad30239b5b



ย  ์ด๋ ‡๊ฒŒ ์ฐพ์•„์ง„ ํ–‰๊ณผ ์—ด์˜ ๊ฒฝ๊ณ„๋ฅผ ์ด์šฉํ•˜์—ฌ ์„ ์„ ๊ทธ๋ ค์ฃผ๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”:


2ebcc224eadc78ee39f698a518d604032cce5b1596d6c4521a234c




ย  ์„ ์„ ๊ทธ๋ฆฌ๋Š” ๊ฒƒ์€ ๋‹จ์ˆœํžˆ MakeLines๋ฅผ ์ด์šฉํ•ด์„œ ์‰ฝ๊ฒŒ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์—ˆ๊ณ , ๋‹ค๋งŒ ์„ ์ด ๊ทธ๋ ค์ง€๋Š” ์œ„์น˜๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” ๊ณผ์ •์—์„œ ์–ธ๋ฆฌ์–ผ ์—”์ง„์ด UI ํŠธ๋žœ์Šคํผ์„ ์–ด๋–ป๊ฒŒ ๋‹ค๋ฃจ๋Š”์ง€์— ๋Œ€ํ•œ ์ดํ•ด๊ฐ€ ๋ถ€์กฑํ•ด ์• ๋ฅผ ๋จน์—ˆ๋˜ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๊ฒฐ๋ก ์ ์œผ๋กœ๋Š” GridTableDecorator๋ฅผ ์ด์šฉํ•ด์„œ ์†์‰ฝ๊ฒŒ GridTable์„ ๊พธ๋ฏธ๊ณ  ์œ ์—ฐํ•œ ํ‘œ ๋””์ž์ธ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.



๋.