eca5765bad4a842ebc4d91eb085cb8595ce51b1c
[tpg/acess2.git] / Usermode / Applications / axwin3_src / WM / renderers / richtext.c
1 /*
2  * Acess2 Window Manager v3
3  * - By John Hodge (thePowersGang)
4  *
5  * render/richtext.c
6  * - Formatted Line Editor
7  */
8 #include <common.h>
9 #include <wm_renderer.h>
10 #include <richtext_messages.h>
11 #include <stdio.h>      // sscanf
12
13 #define LINES_PER_BLOCK 30
14
15 // === TYPES ===
16 typedef struct sRichText_LineBlock
17 {
18         struct sRichText_LineBlock      *Next;
19          int    FirstLine;
20         char    *Lines[LINES_PER_BLOCK];
21 } tRichText_LineBlock;
22 typedef struct sRichText_Window
23 {
24          int    DispLines, DispCols;
25          int    FirstVisRow, FirstVisCol;
26          int    nLines, nCols;
27          int    CursorRow, CursorCol;
28         tRichText_LineBlock     FirstBlock;
29         tColour DefaultFG;
30         tColour DefaultBG;
31         tFont   *Font;
32         
33         short   LineHeight;
34 } tRichText_Window;
35
36 // === PROTOTYPES ===
37  int    Renderer_RichText_Init(void);
38 tWindow *Renderer_RichText_Create(int Flags);
39 void    Renderer_RichText_Redraw(tWindow *Window);
40  int    Renderer_RichText_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data);
41
42 // === GLOBALS ===
43 tWMRenderer     gRenderer_RichText = {
44         .Name = "RichText",
45         .CreateWindow   = Renderer_RichText_Create,
46         .Redraw         = Renderer_RichText_Redraw,
47         .HandleMessage  = Renderer_RichText_HandleMessage
48 };
49
50 // === CODE ===
51 int Renderer_RichText_Init(void)
52 {
53         WM_RegisterRenderer(&gRenderer_RichText);       
54         return 0;
55 }
56
57 tWindow *Renderer_RichText_Create(int Flags)
58 {
59         tRichText_Window        *info;
60         tWindow *ret = WM_CreateWindowStruct( sizeof(*info) );
61         if(!ret)        return NULL;
62         info = ret->RendererInfo;
63         // Everything starts at zero?
64         return ret;
65 }
66
67 static inline int Renderer_RichText_RenderText_Act(tWindow *Window, tRichText_Window *info, int X, int Row, const char *Text, int Bytes, tColour FG, tColour BG)
68 {
69          int    rwidth;
70         // TODO: Fill only what is needed
71         WM_Render_DrawRect(Window, X, Row*info->LineHeight,
72                 Window->W - X, info->LineHeight,
73                 BG
74                 );
75         rwidth = WM_Render_DrawText(Window,
76                 X, Row*info->LineHeight,
77                 Window->W - X, info->LineHeight,
78                 info->Font, FG,
79                 Text, Bytes
80                 );
81         return rwidth;
82 }
83
84 void Renderer_RichText_RenderText(tWindow *Window, int Line, const char *Text)
85 {
86         tRichText_Window        *info = Window->RendererInfo;
87         tColour fg = info->DefaultFG;
88         tColour bg = info->DefaultBG;
89          int    bBold = 0;
90          int    bULine = 0;
91          int    bItalic = 0;
92          int    bRender = 0;
93          int    curx = 0;
94         const char      *oldtext = Text;
95         
96         for( int i = 0; i < info->FirstVisCol + info->DispCols; i ++ )
97         {
98                 char    ch, flags;
99                  int    len;
100
101                 if( i == info->FirstVisCol )
102                         bRender = 1;
103
104                 ch = *Text++;
105                 if( ch == 0 )   break;
106                 if( ch <=3 && bRender ) {
107                         // Render previous characters
108                         curx += Renderer_RichText_RenderText_Act(Window, info, curx, Line,
109                                 oldtext, Text - oldtext, fg, bg);
110                         oldtext = Text;
111                 }
112                 switch(ch)
113                 {
114                 case 1: // FG Select (\1 RRGGBB)
115                         len = sscanf(Text, "%6x", &fg);
116                         if( len != 6 ) {
117                                 // Bad client
118                         }
119                         Text += len;
120                         break ;
121                 case 2: // BG Select (\2 RRGGBB)
122                         len = sscanf(Text, "%6x", &bg);
123                         if( len != 6 ) {
124                                 // Bad client
125                         }
126                         Text += len;
127                         break ;
128                 case 3: // Flagset (0,it,uline,bold)
129                         len = sscanf(Text, "%1x", &flags);
130                         if( len != 1 ) {
131                                 // Bad client
132                         }
133                         Text += len;
134                         bItalic = !!(flags & (1 << 2));
135                         bULine = !!(flags & (1 << 1));
136                         bBold = !!(flags & (1 << 0));
137                         break ;
138                 default: // Any char, nop
139                         break;
140                 }
141         }
142         curx += Renderer_RichText_RenderText_Act(Window, info, curx, Line, oldtext, Text - oldtext, fg, bg);
143         WM_Render_DrawRect(Window, curx, Line * info->LineHeight, Window->W - curx, info->LineHeight, info->DefaultBG);
144 }
145
146 void Renderer_RichText_Redraw(tWindow *Window)
147 {
148         tRichText_Window        *info = Window->RendererInfo;
149          int    i;
150         tRichText_LineBlock     *lines = &info->FirstBlock;
151         
152         // Locate the first line block
153         for( i = info->FirstVisRow; i > LINES_PER_BLOCK && lines; i -= LINES_PER_BLOCK )
154                 lines = lines->Next;
155
156         for( i = 0; i < info->DispLines && lines; i ++ )
157         {
158                 if( i >= info->nLines - info->FirstVisRow )
159                         break;
160                 // TODO: Dirty rectangles?
161                 WM_Render_DrawRect(Window,
162                         0, i*info->LineHeight,
163                         Window->W, info->LineHeight,
164                         info->DefaultBG
165                         );
166                 // TODO: Horizontal scrolling?
167                 // TODO: Formatting
168                 //Renderer_RichText_RenderText(Window, i, lines->Lines[i % LINES_PER_BLOCK]);
169                 WM_Render_DrawText(Window,
170                         0, i*info->LineHeight,
171                         Window->W, info->LineHeight,
172                         info->Font, info->DefaultFG,
173                         lines->Lines[i % LINES_PER_BLOCK],
174                         -1);
175         
176                 if( (i + 1) % LINES_PER_BLOCK == 0 )
177                         lines = lines->Next;
178         }
179         // Clear out i -- info->DispLines
180         WM_Render_DrawRect(Window,
181                 0, i*info->LineHeight,
182                 Window->W, (info->DispLines-i)*info->LineHeight,
183                 info->DefaultBG
184                 );
185 }
186
187 int Renderer_RichText_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data)
188 {
189         switch(Msg)
190         {
191         case MSG_RICHTEXT_SETATTR:
192                 break;
193         }
194         return 0;
195 }

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