Usermode/AxWin4 - Shared buffers working, added DrawCtrl code
[tpg/acess2.git] / Usermode / Applications / axwin4_src / Server / draw_control.cpp
1 /*
2  * Acess2 GUI v4
3  * - By John Hodge (thePowersGang)
4  *
5  * draw_control.cpp
6  * - Common "Control" Drawing
7  *
8  * Handles drawing of resizable controls defined by a bitmap and four region sizes
9  */
10 #include <draw_control.hpp>
11
12 // === CODE ===
13 namespace AxWin {
14
15 CControl::CControl(int EdgeX, int FillX, int InnerX, int EdgeY, int FillY, int InnerY, ::std::vector<uint32_t>&& data):
16         m_edge_x(EdgeX),
17         m_fill_x(FillX),
18         m_inner_x(InnerX),
19         m_edge_y(EdgeY),
20         m_fill_y(FillY),
21         m_inner_y(InnerY),
22         m_data(data)
23 {
24         
25 }
26
27 void CControl::Render(CSurface& dest, const CRect& rect) const
28 {
29         if( rect.m_w < m_edge_x*2 + m_fill_x*2 + m_inner_x )
30                 return ;
31         if( rect.m_h < m_edge_y*2 + m_fill_y*2 + m_inner_y )
32                 return ;
33         
34         const int ctrl_width = m_edge_x + m_fill_x + m_inner_x + (m_inner_x ? m_fill_x : 0) + m_edge_x;
35         
36         const int top_fill_end = rect.m_h / 2 - m_inner_y;
37         const int bot_fill_start = top_fill_end + m_inner_y;
38         const int bot_fill_end   = rect.m_h - m_edge_y;
39         
40         ::std::vector<uint32_t> scanline( rect.m_w );
41          int    y = 0;
42          int    base_ofs = 0;
43         // EdgeY
44         for( int i = 0; i < m_edge_y; i ++ )
45                 renderLine(dest, y++, scanline, rect, &m_data[(base_ofs+i)*ctrl_width]);
46         base_ofs += m_edge_y;
47         // FillY
48         while( y < top_fill_end )
49         {
50                 for( int i = 0; i < m_fill_y && y < top_fill_end; i ++ )
51                         renderLine(dest, y++, scanline, rect, &m_data[(base_ofs+i)*ctrl_width]);
52         }
53         base_ofs += m_fill_y;
54         // InnerY
55         if( m_inner_y > 0 )
56         {
57                 for( int i = 0; i < m_inner_y; i ++ )
58                         renderLine(dest, y++, scanline, rect, &m_data[(base_ofs+i)*ctrl_width]);
59                 base_ofs += m_inner_y;
60         }
61         else
62         {
63                 base_ofs -= m_fill_x;
64         }
65         // FillY
66         while( y < bot_fill_end )
67         {
68                 for( int i = 0; i < m_fill_y && y < bot_fill_end; i ++ )
69                         renderLine(dest, y++, scanline, rect, &m_data[(base_ofs+i)*ctrl_width]);
70         }
71         base_ofs += m_fill_y;
72         // EdgeY
73         for( int i = 0; i < m_edge_y; i ++ )
74                 renderLine(dest, y++, scanline, rect, &m_data[(base_ofs+i)*ctrl_width]);
75         base_ofs += m_edge_y;
76 }
77
78 void CControl::renderLine(CSurface& dest, int y, ::std::vector<uint32_t>& scanline, const CRect& rect, const uint32_t* ctrl_line) const
79 {
80         const int left_fill_end = rect.m_w / 2 - m_inner_x;
81         const int right_fill_end = rect.m_w - m_edge_x;
82         
83          int    x = 0;
84          int    base_ofs = 0;
85         // EdgeX
86         for( int i = 0; i < m_edge_x; i ++ )
87                 scanline[x++] = ctrl_line[base_ofs + i];
88         base_ofs += m_edge_x;
89         // FillX
90         while( x < left_fill_end )
91         {
92                 for( int i = 0; i < m_fill_x && x < left_fill_end; i ++ )
93                         scanline[x++] = ctrl_line[base_ofs + i];
94         }
95         base_ofs += m_fill_x;
96         // InnerX
97         if( m_inner_x > 0 )
98         {
99                 for( int i = 0; i < m_inner_x; i ++ )
100                         scanline[x++] = ctrl_line[base_ofs + i];
101                 base_ofs += m_inner_x;
102         }
103         else
104         {
105                 base_ofs -= m_fill_x;
106         }
107         // FillX
108         while( x < right_fill_end )
109         {
110                 for( int i = 0; i < m_fill_x && x < right_fill_end; i ++ )
111                         scanline[x++] = ctrl_line[base_ofs + i];
112         }
113         base_ofs += m_fill_x;
114         // EdgeX
115         for( int i = 0; i < m_edge_x; i ++ )
116                 scanline[x++] = ctrl_line[base_ofs + i];
117         base_ofs += m_edge_x;
118         
119         dest.DrawScanline(rect.m_y + y, rect.m_x, rect.m_w, scanline.data());
120 }
121
122 // ---- Standard Controls ---
123 // Standard button control
124 CControl StdButton(2, 1, 0, 2, 1, 0, ::std::vector<uint32_t> {
125         0xC0C0C0, 0xC0C0C0, 0xC0C0C0, 0xC0C0C0, 0xC0C0C0,
126         0xC0C0C0, 0xFFD0D0, 0xFFD0D0, 0xFFD0D0, 0xC0C0C0,
127         0xC0C0C0, 0xFFD0D0, 0xFFD0D0, 0xFFD0D0, 0xC0C0C0,
128         0xC0C0C0, 0xFFD0D0, 0xFFD0D0, 0xFFD0D0, 0xC0C0C0,
129         0xC0C0C0, 0xC0C0C0, 0xC0C0C0, 0xC0C0C0, 0xC0C0C0,
130         });
131
132 // Text Area
133 CControl StdText(2, 1, 0, 2, 1, 0, ::std::vector<uint32_t> {
134         0x000000, 0x000000, 0x000000, 0x000000, 0x000000,
135         0x000000, 0xA0A0A0, 0x0A0000, 0xA0A0A0, 0x000000,
136         0x000000, 0xA0A0A0, 0xFFFFFF, 0xA0A0A0, 0x000000,
137         0x000000, 0xA0A0A0, 0x0A0000, 0xA0A0A0, 0x000000,
138         0x000000, 0x000000, 0x000000, 0x000000, 0x000000,
139         });
140
141 const CControl* CControl::GetByName(const ::std::string& name)
142 {
143         if( name == "StdButton" )
144                 return &StdButton;
145         if( name == "StdText" )
146                 return &StdText;
147         // TODO: Use another exception
148         return nullptr;
149 }
150
151 const CControl* CControl::GetByID(uint16_t id)
152 {
153         switch(id)
154         {
155         case 0x00:      return &StdButton;
156         case 0x01:      return &StdText;
157         default:        return nullptr;
158         }
159 }
160
161 };      // AxWin
162

UCC git Repository :: git.ucc.asn.au