GacUI支持包括GIF和PNG在内的多种图片格式
自从我发现Windows XP开始就支持Windows Image Component之后,我发现读取图片这个问题瞬间就变简单了。因此我给GacUI添加了绘制图片的功能,并做了一个小小的GIF动画demo。代码仍然更新在了 Vczh Library++3.0上的Candidate\GUI\GUIDemo\GUIDemo.sln上。F5可以直接运行,不过如果要双击打开exe的话,则要把GUIDemo\Resources目录复制到exe目录下。下面的效果图展示了一个GIF动画上覆盖若干个带有alpha通道的png图片:
(实际效果是会动的)
因为GacUI试图隔离Windows API的所有信息,以便可以让程序员自由添加对操作系统(Windows或其他)和渲染技术(GDI、Direct2D或其他)的支持,因此我不得不暂时封装了一下。现在的这个接口只能读,不能做一些高级操作,以后会添加上。使用GacUI编写上述Demo的代码如下(具体实现可以去下载并阅读):
1
#include
"
..\..\GUI\GacUI.h
"
2
3 GuiBoundsComposition * CreateImageFrame(Ptr < INativeImage > image, int frameIndex = 0 )
4 {
5 GuiImageFrameElement * element = GuiImageFrameElement::Create();
6 element -> SetImage(image, frameIndex);
7
8 GuiBoundsComposition * composition = new GuiBoundsComposition;
9 composition -> SetOwnedElement(element);
10 composition -> SetMinSizeLimitation(GuiGraphicsComposition::LimitToElement);
11 return composition;
12 }
13
14 class GifAnimation : public Object, public IGuiGraphicsAnimation
15 {
16 protected :
17 unsigned __int64 startTime;
18 GuiImageFrameElement * element;
19 public :
20 GifAnimation(GuiImageFrameElement * _element)
21 :element(_element)
22 ,startTime(DateTime::LocalTime().totalMilliseconds)
23 {
24 }
25
26 int GetTotalLength()
27 {
28 return 1 ;
29 }
30
31 int GetCurrentPosition()
32 {
33 return 0 ;
34 }
35
36 void Play( int currentPosition, int totalLength)
37 {
38 unsigned __int64 ms = DateTime::LocalTime().totalMilliseconds - startTime;
39 int frameIndex = (ms / 100 ) % element -> GetImage() -> GetFrameCount();
40 element -> SetImage(element -> GetImage(), frameIndex);
41 }
42
43 void Stop()
44 {
45 }
46 };
47
48 void SetupGifWindow(GuiControlHost * host)
49 {
50 host -> GetBoundsComposition() -> SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
51 INativeImageProvider * imageProvider = GetCurrentController() -> GetImageProvider();
52 Ptr < INativeImage > imageNew = imageProvider -> CreateImageFromFile(L " Resources\\New.png " );
53 Ptr < INativeImage > imageOpen = imageProvider -> CreateImageFromFile(L " Resources\\Open.png " );
54 Ptr < INativeImage > imageSave = imageProvider -> CreateImageFromFile(L " Resources\\Save.png " );
55 Ptr < INativeImage > imageGif = imageProvider -> CreateImageFromFile(L " Resources\\Gif.gif " );
56
57 GuiBoundsComposition * image1 = CreateImageFrame(imageNew);
58 GuiBoundsComposition * image2 = CreateImageFrame(imageOpen);
59 GuiBoundsComposition * image3 = CreateImageFrame(imageSave);
60 GuiBoundsComposition * image4 = CreateImageFrame(imageGif);
61
62 host -> GetContainerComposition() -> AddChild(image4);
63 host -> GetContainerComposition() -> AddChild(image1);
64 host -> GetContainerComposition() -> AddChild(image2);
65 host -> GetContainerComposition() -> AddChild(image3);
66
67 image1 -> SetBounds(Rect(Point( 10 , 10 ), imageNew -> GetFrame( 0 ) -> GetSize()));
68 image2 -> SetBounds(Rect(Point( 50 , 10 ), imageOpen -> GetFrame( 0 ) -> GetSize()));
69 image3 -> SetBounds(Rect(Point( 90 , 10 ), imageSave -> GetFrame( 0 ) -> GetSize()));
70
71 Ptr < GifAnimation > animation = new GifAnimation(image4 -> GetOwnedElement().Cast < GuiImageFrameElement > ().Obj());
72 host -> GetGraphicsHost() -> GetAnimationManager() -> AddAnimation(animation);
73 }
74
75 /* **********************************************************************
76 GuiMain
77 ********************************************************************** */
78
79 void GuiMain()
80 {
81 INativeWindow * window = GetCurrentController() -> CreateNativeWindow();
82 #ifdef GUI_GRAPHICS_RENDERER_GDI
83 window -> SetTitle(L " Vczh GUI Demo (GDI) " );
84 #endif
85 #ifdef GUI_GRAPHICS_RENDERER_DIRECT2D
86 window -> SetTitle(L " Vczh GUI Demo (Direct2D) " );
87 #endif
88 window -> SetClientSize(Size( 800 , 600 ));
89
90 INativeScreen * screen = GetCurrentController() -> GetScreen(window);
91 Rect windowBounds = window -> GetBounds();
92 Rect screenBounds = screen -> GetClientBounds();
93 window -> SetBounds(Rect(
94 Point(
95 screenBounds.Left() + (screenBounds.Width() - windowBounds.Width()) / 2 ,
96 screenBounds.Top() + (screenBounds.Height() - windowBounds.Height()) / 2
97 ),
98 windowBounds.GetSize()
99 ));
100
101 GuiControlHost host( new win7::Win7WindowStyle);
102 SetupGifWindow( & host);
103 host.SetNativeWindow(window);
104
105 GetCurrentController() -> Run(window);
106 }
2
3 GuiBoundsComposition * CreateImageFrame(Ptr < INativeImage > image, int frameIndex = 0 )
4 {
5 GuiImageFrameElement * element = GuiImageFrameElement::Create();
6 element -> SetImage(image, frameIndex);
7
8 GuiBoundsComposition * composition = new GuiBoundsComposition;
9 composition -> SetOwnedElement(element);
10 composition -> SetMinSizeLimitation(GuiGraphicsComposition::LimitToElement);
11 return composition;
12 }
13
14 class GifAnimation : public Object, public IGuiGraphicsAnimation
15 {
16 protected :
17 unsigned __int64 startTime;
18 GuiImageFrameElement * element;
19 public :
20 GifAnimation(GuiImageFrameElement * _element)
21 :element(_element)
22 ,startTime(DateTime::LocalTime().totalMilliseconds)
23 {
24 }
25
26 int GetTotalLength()
27 {
28 return 1 ;
29 }
30
31 int GetCurrentPosition()
32 {
33 return 0 ;
34 }
35
36 void Play( int currentPosition, int totalLength)
37 {
38 unsigned __int64 ms = DateTime::LocalTime().totalMilliseconds - startTime;
39 int frameIndex = (ms / 100 ) % element -> GetImage() -> GetFrameCount();
40 element -> SetImage(element -> GetImage(), frameIndex);
41 }
42
43 void Stop()
44 {
45 }
46 };
47
48 void SetupGifWindow(GuiControlHost * host)
49 {
50 host -> GetBoundsComposition() -> SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
51 INativeImageProvider * imageProvider = GetCurrentController() -> GetImageProvider();
52 Ptr < INativeImage > imageNew = imageProvider -> CreateImageFromFile(L " Resources\\New.png " );
53 Ptr < INativeImage > imageOpen = imageProvider -> CreateImageFromFile(L " Resources\\Open.png " );
54 Ptr < INativeImage > imageSave = imageProvider -> CreateImageFromFile(L " Resources\\Save.png " );
55 Ptr < INativeImage > imageGif = imageProvider -> CreateImageFromFile(L " Resources\\Gif.gif " );
56
57 GuiBoundsComposition * image1 = CreateImageFrame(imageNew);
58 GuiBoundsComposition * image2 = CreateImageFrame(imageOpen);
59 GuiBoundsComposition * image3 = CreateImageFrame(imageSave);
60 GuiBoundsComposition * image4 = CreateImageFrame(imageGif);
61
62 host -> GetContainerComposition() -> AddChild(image4);
63 host -> GetContainerComposition() -> AddChild(image1);
64 host -> GetContainerComposition() -> AddChild(image2);
65 host -> GetContainerComposition() -> AddChild(image3);
66
67 image1 -> SetBounds(Rect(Point( 10 , 10 ), imageNew -> GetFrame( 0 ) -> GetSize()));
68 image2 -> SetBounds(Rect(Point( 50 , 10 ), imageOpen -> GetFrame( 0 ) -> GetSize()));
69 image3 -> SetBounds(Rect(Point( 90 , 10 ), imageSave -> GetFrame( 0 ) -> GetSize()));
70
71 Ptr < GifAnimation > animation = new GifAnimation(image4 -> GetOwnedElement().Cast < GuiImageFrameElement > ().Obj());
72 host -> GetGraphicsHost() -> GetAnimationManager() -> AddAnimation(animation);
73 }
74
75 /* **********************************************************************
76 GuiMain
77 ********************************************************************** */
78
79 void GuiMain()
80 {
81 INativeWindow * window = GetCurrentController() -> CreateNativeWindow();
82 #ifdef GUI_GRAPHICS_RENDERER_GDI
83 window -> SetTitle(L " Vczh GUI Demo (GDI) " );
84 #endif
85 #ifdef GUI_GRAPHICS_RENDERER_DIRECT2D
86 window -> SetTitle(L " Vczh GUI Demo (Direct2D) " );
87 #endif
88 window -> SetClientSize(Size( 800 , 600 ));
89
90 INativeScreen * screen = GetCurrentController() -> GetScreen(window);
91 Rect windowBounds = window -> GetBounds();
92 Rect screenBounds = screen -> GetClientBounds();
93 window -> SetBounds(Rect(
94 Point(
95 screenBounds.Left() + (screenBounds.Width() - windowBounds.Width()) / 2 ,
96 screenBounds.Top() + (screenBounds.Height() - windowBounds.Height()) / 2
97 ),
98 windowBounds.GetSize()
99 ));
100
101 GuiControlHost host( new win7::Win7WindowStyle);
102 SetupGifWindow( & host);
103 host.SetNativeWindow(window);
104
105 GetCurrentController() -> Run(window);
106 }