[UX Summit 요약] 델파이로 윈도우10에서 멋진 플루언트 UI 룩앤필을 구현하기 #2
- 2021-03-04
- Posted by: Narae Kim
- Category: 기술자료
댓글 없음
- 원본 비디오 시청: https://youtu.be/lGcj8AG7M0o
- 발표자료 및 원본 아티클: https://www.codedotshow.com/blog/how-to-give-your-apps-the-really-cool-windows-10-fluent-ui-look-and-feel-with-delphi-part-two/
- 사용된 FluentUI 구현 소스 코드 다운로드(깃허브): https://github.com/checkdigits/fancy_ui
- UX Summit 전체 보기 (현재 무료, 향후 유료 전환 예상): summit.desktopfirst.com/replays/
- 데브기어의 UX Summit 소개 페이지로 가기: https://devgear.co.kr/archives/3600
윈도우10에 멋진 플루언트UI 룩앤필을 델파이로 구현하기 (Giving your Apps the Fluent UI Look and Feel with Delphi ) 1편에 이어, 2편의 핵심을 요약 번역하였습니다. (이 요약 번역은 Q&A등 일부 생략되었을 수 있습니다. 1편 링크: https://devgear.co.kr/archives/3680)
1편에서는,
마이크로소프트의 새 표준 디자인 컨셉인 플루언트UI가 무엇인지이 무엇인지, 핵심 요소는 무엇인지, 윈도우10에 어떻게 반영되었는지를 설명하였습니다. 더 세련되진 윈도우10의 룩앤필과 UX를 델파이 앱에 적용하기 위해 개발자가 꼭 알아야할 핵심 개념과 관련 델파이 기술이 정리되어 있습니다.
이번 2편에서는,
- 델파이 개발자들이 플루언트UI를 구현하는 방법을 데모와 함께 설명합니다. (써드파티를 사용할 수도 있고, 순수 델파이 코드만으로도 가능합니다.)
- 소스 코드는 깃허브(https://github.com/checkdigits/fancy_ui)에 무료로 공개되어 있습니다.
- 비디오를 보면 훨씬 이해가 잘될 것입니다. [비디오]와 함께 보기를 권합니다.
목차
- 마이크로소프트 플루언트UI의 핵심 요소 5가지 (1편 내용 재정리)
- 데모: 델파이로 구현한 플루언트UI를 델파이로 구현한 앱 실행 화면 (비디오 12분 50초 부터)
- 데모: 델파이 내장 컴포넌트로만 플루언트UI를 구현한 앱 작동 및 구현 방법 설명 (비디오 19분 49초 부터)
- 데모: Almedia 컴포넌트로 플루언트UI를 구현한 앱 작동 및 구현 방법 설명 (비디오 30분 55초 부터)
마이크로소프트 플루언트UI의 핵심 요소 5가지 (1편 내용 재정리)
마이크로소프트 플루언트UI의 핵심 요소 5가지 1편의 내용을 정리 요약한 것입니다.
더 자세한 내용은 1편에서 확인하세요: https://tech.devgear.co.kr/467866
- 빛(Light)
- 포커스 표현(Reveal Focus): 포커스를 받은 요소의 테두리를 눈에 띄도록 표시
- 강조 표현(Reveal Highlight): 마우스가 위치한 곳을 더 밝게 표시
- 깊이(Depth)
- 오피스2019 앱을 실행하면 나타나는 첫 화면에 잘 나타남
- 클릭할 수 있는 요소 역시 평소에는 평면이지만, 포커스를 받으면 그림자와 함께 3차원으로 튀어나와 보임
- 모션(Motion)
- 윈도우10 메일 앱을 열면 나타나는 화면에서 잘 나타남
- 앱의 배경인 구름이 흘러가는 것이 표현되어 생동감을 줌
- 폰트와 아이콘 (Font & Icon)
- Segoe UI 폰트 (평소에는 Segue UI의 light 폰트) 와 아이콘으로 통일됨
- 재질(Material)
- 아크릴 바탕(Acrylic), 뒤에 있는 화면을 완전히 가리지 않고 반투명으로 표현, 투명도 적용
데모: 델파이로 구현한 플루언트UI를 델파이로 구현한 앱 실행 화면 보기 (비디오 19분 51초 부터)
데모: 델파이 내장 컴포넌트로만 플루언트UI를 구현한 앱 작동 및 구현 방법 설명 (비디오 19분 49초 부터)
- ‘플루언트UI의 빛(Light)-포커스’ 구현을 버튼에 하기: 우측 상단의 최소화 버튼 (비디오 20분 43초 부터)
- TRectangle [최소화 버튼] 이미지를 넣고, 그 안에 TFillRGBEffect를 넣고 마우스 오버일 때 작동하도록 설정한다.
- ‘플루언트UI의 깊이(Depth)’ 구현: 섹션 카드 (비디오 21분 28초 부터)
- TRoundRectangle 안에 TLabel과 TShadowEffect를 넣고 마우스 오버일 때 작동하도록 설정한다.
(TShadowEffect의 Enabled 속성이 True 이면 그림자가 표시된다)
- TRoundRectangle 안에 TLabel과 TShadowEffect를 넣고 마우스 오버일 때 작동하도록 설정한다.
- ‘플루언트UI의 재질(Material)’ 구현: 화면의 왼쪽 영역 (비디오 22분 42초 부터)
- 투명도 구현은 생각보다 쉽다 (의외로 많은 사람들이 어렵거나 불편한 방법을 사용하고 있다)
- VCL에서는 TForm의 (AlphaBlend속성이 True이고) AlphaBlendValue가 255이면 불투명이다. 값이 0으로 가까이 갈 수록 더 투명해진다.
- FMX는 화면 그리기 방식이 VCL과 다르다. TForm의 Transparency 속성을 True로 주면 투명해진다. 그리고 나서 각 섹션에서 Opacity 속성을 사용해 투명도를 정한다.
- 이 데모의 FXM 폼에서는 BorderStyle 속성을 None으로 주어 테두리가 평소에 보이지 않도록 했다.
- 그리고 나서 화면 왼쪽의 TPanel의 Opacity 속성을 0~1 사이 값으로 설정하여 조절한다. (1 이면 완전히 불투명하다)
- 이 데모의 TPanel의 투명도를 설정하는 부분은 우측 본 화면의 아래 쪽에 있다.
- TSpinBox를 통해 값을 받는다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// TSpinBox의 OnChange 이벤트를 처리하는 코드 // 0˜10까지 값을 받으면, 해당하는 Opacity(0~1)가 반영되도록 한다. procedure TForm1.SpinBox1Change(Sender: TObject); begin if SameText(Spinbox1.Text, '10') then Panel1.Opacity := 1 else Panel1.Opacity := StrToFloat('0.' + Spinbox1.Text); end; |
- ‘플루언트UI의 빛(Light)-포커스’ 구현을 폼 자체에 하기 (비디오 25분 19초 부터)
- 멀티플랫폼용인 FMX에서는 TForm의 OnActivate와 OnDeactivate 이벤트에서 포커스를 받았는지를 알 수 있다.
- 참고로, 윈도우 전용인 VCL에서는 TApplication의 이벤트을 사용해야 포커스를 받았는지를 알 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
// ‘플루언트UI의 빛(Light)-포커스’를 OnActivate에서 강조, OnDeactivate에서 해제하는 코드 // [참고]윈도우 전용인 VCL에서는 TApplication을 사용해야 포커스를 받았는지를 알 수 있지만, // 멀티플랫폼용인 FMX에서는 TForm에서 가능하다 procedure TForm1.FormActivate(Sender: TObject); begin UpdateFocus(True); end; procedure TForm1.FormDeactivate(Sender: TObject); begin UpdateFocus(False); end; procedure TForm1.UpdateFocus(const IsFocussed: Boolean); begin // 창이 선택된 상태이고 AND 창이 최대화되지 않은 상태라면 // 창의 테두리 선을 표시하여 강조한다. if IsFocussed and (WindowState <> TWindowState.wsMaximized) then begin Line1.Stroke.Color := GetAccentColor(claRed); FillRGBEffect2.Color := Line1.Stroke.Color; FillRGBEffect3.Color := Line1.Stroke.Color; UpdateTransparency; end else begin Line1.Stroke.Color := claWhite; UpdateTransparency; // 창이 최대화된 경우, 투명도가 적용되지 않아야 한다. end; Line2.Stroke.Color := Line1.Stroke.Color; Line3.Stroke.Color := Line1.Stroke.Color; Line4.Stroke.Color := Line1.Stroke.Color; end; |
- 가장 윗쪽 툴바에서 마우스를 누른 상태로 창의 위치를 옮기도록 구현 하기 (비디오 26분 57초 부터)
- Mousedown 이벤트를 사용한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// 창에 Title Bar가 없는 경우, 가장 윗쪽 툴바를 마우스로 누른 상태로 창의 위치를 옮길 수 있도록 하는 코드 // Mousedown 이벤트를 사용한다. procedure TForm1.Panel7MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single); begin if (Button = TMouseButton.mbLeft) then if WindowState <> TWindowState.wsMaximized then StartWindowDrag; end; |
- 사용자가 윈도우에서 설정한 ‘강조색(Accent Color)’ 알아내기 (비디오 27분 59초 부터)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
// 사용자가 윈도우에서 설정한 ‘강조색(Accent Color)’ 알아내는 코드 function GetAccentColor(const TheDefault: TColor): TColor; const TheKey = 'SOFTWARE\Microsoft\Windows\DWM\'; TheValue = 'AccentColor'; var Reg: TRegistry; AccentCol: DWord; sStr: string; begin // 데스크톱 윈도우 관리자에 없는 값을 아래 레지스트리에서 가져올 수 있다: // \\HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\DWM\ // // 이 레지스트리에서 "AccentColor"의 DWORD 값을 찾는다. 이값은 창 테두리, 엣지 브라우저의 텝 등등에 적용된다. // // 해당 키의 전체 경로: // \\HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\DWM\AccentColor // Result := TheDefault; Reg := TRegistry.Create(KEY_READ); try Reg.RootKey := HKEY_CURRENT_USER; if Reg.KeyExists(TheKey) then if Reg.OpenKey(TheKey, False) then try if Reg.ValueExists(TheValue) then begin AccentCol := Reg.ReadInteger(TheValue); // AccentColor를 읽어서 8자리 헥사(Hex) 숫자로 변환 sStr := IntToHex(AccentCol, 8); // (Hex 값임을 표시하는) 첫 2자리 0x를 제거 sStr := Copy(sStr, 3, Length(sStr) - 2); // 이제, "$FF"를 앞에 놓고 RGB값을 뒤에서부터 떼어내어 델파이의 TColor에 맞추기 // // [참고] 델파이의 TColor에 맞추는 방법으로 GetRValue(), GetGValue() 등 훨씬 좋은 것들이 있다. // 이 방법을 쓰는 이유는, 편한 함수를 제공하는 유닛을 포함하지 않아도 되기 때문일 뿐이다. Result := TColor(StrToIntDef('$ff' + Copy(sStr, 5, 2) + Copy(sStr, 3, 2) + Copy(sStr, 1, 2), TheDefault)); end; finally Reg.CloseKey; end; finally Reg.Free; end; end; |
데모: Almedia 컴포넌트로 플루언트UI를 구현한 앱 작동 및 구현 방법 설명 (비디오 30분 55초 부터)
- Almedia 컴포넌트는 플루언트UI를 미리 반영해두었으므로, 바로 사용하면 된다.
- 예를 들어, TscStyledForm에는 FluentUIAcrylicColor, FluentUIBackground, FluentUIBorder…의 속성이 이미 있다.
- 라이선스 가격은 US$99 이며, 업데이트가 평생 무료로 제공된다. (다른 소프트웨어와 매우 다른 경우이다)
- 참고로, 발표자(Ian Barker)는 Almedia 컴포넌트와 아무 관련이 없고, 단지 좋아해서 소개하는 것일 뿐이다.
- 윈도우10 테마에 사용할 수 있는 델파이 테마
- 델파이의 ‘Windows10’ VCL 테마는 윈도우10 라이트 모드에 가장 잘 맞음
- 델파이의 ‘Tablet Dark’ VCL 테마는 윈도우10 다크 모드에 가장 잘 맞음
- Almedia 컴포넌트는 속성과 메소드가 매우 많아서 처음에 혼란스러울 수 있다. 하지만, 일단 한번 하고 나면, 훨씬 쉬울 것이고, 매우 유용한 컴포넌트임을 알 수 있을 것이다.
- 이와 별개로, FMX 역시 UI구현이 매우 유연하고 강력하므로 FMX만 가지고 (소스 코드를 쓰지 않고) 플루언트UI를 구현하는 것도 매우 쉬웠다.
- 플루언트UI는 훨씬 더 많은 것들이 있다. 이 세션의 간단한 데모는 플루언트UI의 핵심을 중심으로 다루었으므로 좋은 시작점이 될 것이다. 이 세션에는 없지만 모션(Motion)을 구현하려면 Animation 을 사용하면 된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
// AlmediaDev 컴포넌트로 개발하는 경우에도, 윈도우 테마를 맞춰주는 코드가 필요하다 procedure TVCLCalculatorForm.FormCreate(Sender: TObject); begin MatchWindowsTheme; ... end; // 윈도우 테마를 맞춰주는 코드 // [참고] Font.Color는 clWindows로, Font.Name은 Segoe로 되어 있어야 한다. procedure TVCLCalculatorForm.MatchWindowsTheme; var GoDark: Boolean; iInt: Integer; AButton: TComponent; begin // 델파이의 'Tablet Dark' VCL 테마는 윈도우10 다크 모드에 가장 잘 맞음 // 델파이의 'Windows10' VCL 테마는 윈도우10 라이트 모드에 가장 잘 맞음 SetAppropriateThemeMode('Tablet Dark', 'Windows10'); GoDark := DarkModeIsEnabled; // 이 코드는 Carbon 테마가, 윈도우 다크 테마와 잘 맞지 않기 때문임 for iInt in cNumberButtons do begin AButton := FindComponent('scGPButton' + IntToStr(iInt)); if (AButton <> Nil) then if (AButton is TscGPButton) then if GoDark then TscGPButton(AButton).Options.NormalColor := clBackground else TscGPButton(AButton).Options.NormalColor := clWindow; end; end; procedure SetAppropriateThemeMode(const DarkModeThemeName, LightModeThemeName: string); begin SetSpecificThemeMode(DarkModeIsEnabled, DarkModeThemeName, LightModeThemeName); end; procedure SetSpecificThemeMode(const AsDarkMode: Boolean; const DarkModeThemeName, LightModeThemeName: string); var ChosenTheme: string; begin if AsDarkMode then ChosenTheme := DarkModeThemeName else ChosenTheme := LightModeThemeName; TStyleManager.TrySetStyle(ChosenTheme, False); end; |
유용한 링크
- 발표자료 및 원본 아티클: https://www.codedotshow.com/blog/how-to-give-your-apps-the-really-cool-windows-10-fluent-ui-look-and-feel-with-delphi-part-two/
- 사용된 FluentUI 구현 소스 코드 다운로드 (깃허브): https://github.com/checkdigits/fancy_ui
- 마이크로소프트 공식 플루언트 UI 사이트: http://developer.microsoft.com/en-us/fluentui#
- Segoe UI: https://ko.wikipedia.org/wiki/Segoe
- 잘 정리된 블로그: https://medium.com/microsoft-design/how-fluent-ui-unlocks-the-next-generation-of-microsoft-365-experiences-8b24809faf06
- Almedia Dev Style Controls: http://almdev.com
- 원본 비디오 시청: https://youtu.be/lGcj8AG7M0o
- 발표자료 및 원본 아티클: https://www.codedotshow.com/blog/how-to-give-your-apps-the-really-cool-windows-10-fluent-ui-look-and-feel-with-delphi-part-two/
- 사용된 FluentUI 구현 소스 코드 다운로드(깃허브): https://github.com/checkdigits/fancy_ui
- UX Summit 전체 보기 (현재 무료, 향후 유료 전환 예상): summit.desktopfirst.com/replays/
- 데브기어의 UX Summit 소개 페이지로 가기: https://devgear.co.kr/archives/3600
12.0
12.1
AI
AWS
C++
c++빌더
chatgpt
DelphiCon
ios
rad서버
RAD스튜디오
UI
UIUX
UX
uxsummit
vcl
개발
개발사례
고객사례
기술레터
기술백서
데브옵스
데이터
데이터베이스
델파이
리눅스
마이그레이션
맥
머신러닝
모바일
새버전
샘플
세미나
안드로이드
웹
윈도우
인공지능
인터베이스
출시
커뮤니티에디션
코드
클라우드
파이썬
파이어몽키
현대화