Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 6864 → Rev 6865

/contrib/sdk/samples/freetype/txview/winlib/winlib.c
0,0 → 1,615
#include <stdio.h>
#include <string.h>
#include "winlib.h"
 
#define ID_SCROLLER_UP 0x30
#define ID_SCROLLER_DOWN 0x31
#define ID_SCROLLER_THUMB 0x32
 
typedef int v2si __attribute__ ((vector_size (8)));
 
font_t *create_font(void *face, int size);
 
static pos_t old_pos;
ctrl_t *mouse_capture = NULL;
 
 
 
void show_window(window_t *win)
{
BeginDraw();
DrawWindow(0,0,0,0,NULL,0,0x73);
if( (win->win_state != MINIMIZED) &&
(win->win_state != ROLLED) )
show_context(win->ctx);
EndDraw();
}
 
window_t *create_window(char *caption, int style, int x, int y,
int w, int h, handler_t handler)
{
char proc_info[1024];
window_t *win;
 
if(handler==NULL)
return NULL;
 
win = malloc(sizeof(*win));
if(win == NULL)
return NULL;
 
BeginDraw();
DrawWindow(x, y, w+TYPE_3_BORDER_WIDTH*2,
h+TYPE_3_BORDER_WIDTH+get_skin_height(), caption, 0x000000, 0x73);
EndDraw();
 
GetProcInfo(proc_info);
 
x = *(uint32_t*)(proc_info+34);
y = *(uint32_t*)(proc_info+38);
w = *(uint32_t*)(proc_info+42)+1;
h = *(uint32_t*)(proc_info+46)+1;
 
win->handler = handler;
 
list_initialize(&win->link);
list_initialize(&win->child);
 
win->rc.l = x;
win->rc.t = y;
win->rc.r = x + w;
win->rc.b = y + h;
 
win->w = w;
win->h = h;
 
win->client.l = TYPE_3_BORDER_WIDTH;
win->client.t = get_skin_height();
win->client.r = w - TYPE_3_BORDER_WIDTH;
win->client.b = h - TYPE_3_BORDER_WIDTH;
win->clw = win->client.r - win->client.l;
win->clh = win->client.b - win->client.t;
 
win->caption_txt = caption;
win->style = style;
 
win->child_over = NULL;
win->child_focus = NULL;
 
win->ctx = create_context(win->client.l, win->client.t, win->clw, win->clh);
clear_context(win->ctx, 0xFFFFFFFF);
 
win->font = create_font(NULL, 14);
 
send_message((ctrl_t*)win, MSG_CREATE, 0, 0);
send_message((ctrl_t*)win, MSG_DRAW, 0, 0);
 
ctrl_t *child;
 
child = (ctrl_t*)win->child.next;
 
while( &child->link != &win->child)
{
send_message(child, MSG_DRAW, 0, 0);
child = (ctrl_t*)child->link.next;
};
 
show_window(win);
 
return win;
};
 
 
void handle_sys_paint(window_t *win)
{
char proc_info[1024];
int winx, winy, winw, winh;
uint8_t state;
 
GetProcInfo(proc_info);
 
winx = *(uint32_t*)(proc_info+34);
winy = *(uint32_t*)(proc_info+38);
winw = *(uint32_t*)(proc_info+42)+1;
winh = *(uint32_t*)(proc_info+46)+1;
 
state = *(uint8_t*)(proc_info+70);
 
if(state & 2)
{
win->win_state = MINIMIZED;
return;
}
else if(state & 4)
{
win->win_state = ROLLED;
show_window(win);
return;
};
 
if(state & 1)
state = MAXIMIZED;
else
state = NORMAL;
 
if( (win->w != winw) ||
(win->h != winh) )
{
ctrl_t *child;
 
win->client.l = TYPE_3_BORDER_WIDTH;
win->client.t = get_skin_height();
win->client.r = winw - TYPE_3_BORDER_WIDTH;
win->client.b = winh - TYPE_3_BORDER_WIDTH;
win->clw = win->client.r - win->client.l;
win->clh = win->client.b - win->client.t;
 
resize_context(win->ctx, win->clw, win->clh);
 
clear_context(win->ctx, 0xFFFFFFFF);
 
send_message((ctrl_t*)win, MSG_SIZE, 0, 0);
send_message((ctrl_t*)win, MSG_DRAW, 0, 0);
 
child = (ctrl_t*)win->child.next;
 
while( &child->link != &win->child)
{
send_message(child, MSG_DRAW, 0, 0);
child = (ctrl_t*)child->link.next;
};
}
 
win->rc.l = winx;
win->rc.t = winy;
win->rc.r = winx + winw;
win->rc.b = winy + winh;
win->w = winw;
win->h = winh;
win->win_state = state;
 
show_window(win);
};
 
 
ctrl_t *get_child(ctrl_t *ctrl, int x, int y)
{
ctrl_t *child = NULL;
 
ctrl_t *tmp = (ctrl_t*)ctrl->child.next;
 
while( &tmp->link != &ctrl->child )
{
if(pt_in_rect(&tmp->rc, x, y))
{
child = get_child(tmp, x, y);
return child == NULL ? tmp : child;
};
tmp = (ctrl_t*)tmp->link.next;
};
return child;
};
 
 
int send_mouse_message(window_t *win, uint32_t msg)
{
ctrl_t *child;
 
if(mouse_capture)
return send_message(mouse_capture, msg, 0, old_pos.val);
 
child = get_child((ctrl_t*)win, old_pos.x, old_pos.y);
 
if(msg == MSG_MOUSEMOVE)
{
if( win->child_over )
{
if(child == win->child_over)
send_message(child, MSG_MOUSEMOVE, 0, old_pos.val);
else
send_message(win->child_over, MSG_MOUSELEAVE, 0, old_pos.val);
}
else if( child )
send_message(child, MSG_MOUSEENTER, 0, old_pos.val);
 
win->child_over = child;
};
 
if( child )
return send_message(child, msg, 0, old_pos.val);
 
if(pt_in_rect(&win->client, old_pos.x, old_pos.y))
return send_message((ctrl_t*)win, msg, 0, old_pos.val);
 
};
 
#define DBG(x)
 
static void handle_sys_mouse(window_t *win)
{
static uint32_t mouse_click_time;
static int mouse_action;
static int old_buttons;
int buttons;
uint32_t wheels;
uint32_t click_time;
int action;
 
pos_t pos;
 
mouse_action = 0;
pos = get_mouse_pos(POS_WINDOW);
 
if(pos.val != old_pos.val)
{
mouse_action = 0x80000000;
old_pos = pos;
};
// printf("pos x%d y%d\n", pos.x, pos.y);
 
buttons = get_mouse_buttons();
wheels = get_mouse_wheels();
 
// if( wheels & 0xFFFF){
// wheels = (short)wheels>0 ? MSG_WHEELDOWN : MSG_WHEELUP;
// send_mouse_message(win, wheels);
// }
 
if((action = (buttons ^ old_buttons))!=0)
{
mouse_action|= action<<3;
mouse_action|= buttons & ~old_buttons;
}
old_buttons = buttons;
 
if(mouse_action & 0x80000000) {
DBG("mouse move \n\r");
send_mouse_message(win, MSG_MOUSEMOVE);
};
 
if(mouse_action & 0x09)
{
if((mouse_action & 0x09)==0x09)
{
// printf("left button down x= %d y= %d\n\r", old_x.x, old_x.y);
click_time = get_tick_count();
if(click_time < mouse_click_time+35) {
mouse_click_time = click_time;
send_mouse_message(win,MSG_LBTNDBLCLK);
}
else {
mouse_click_time = click_time;
send_mouse_message(win,MSG_LBTNDOWN);
};
}
else {
// printf("left button up \n\r");
send_mouse_message(win,MSG_LBTNUP);
}
};
 
if(mouse_action & 0x12)
{
if((mouse_action & 0x12)==0x12) {
DBG("right button down \n\r");
send_mouse_message(win,MSG_RBTNDOWN);
}
else {
DBG("right button up \n\r");
send_mouse_message(win,MSG_RBTNUP);
};
};
if(mouse_action & 0x24)
{
if((mouse_action & 0x24)==0x24){
DBG("middle button down \n\r");
send_mouse_message(win,MSG_MBTNDOWN);
}
else {
DBG("middle button up \n\r");
send_mouse_message(win,MSG_MBTNUP);
};
};
};
 
 
int handle_system_events(window_t *win)
{
oskey_t key;
 
for (;;)
{
switch (get_os_event())
{
case MSG_SYS_PAINT:
handle_sys_paint(win);
break;
 
case MSG_SYS_KEY:
key = get_key();
printf("key %d\n", key.code);
break;
 
case MSG_SYS_BUTTON:
// button pressed; we have only one button, close
return 0;
 
case MSG_SYS_MOUSE:
handle_sys_mouse(win);
break;
};
 
if( (win->win_state != MINIMIZED) &&
(win->win_state != ROLLED) )
show_context(win->ctx);
}
 
return 0;
}
 
void *create_control(size_t size, int id, int x, int y,
int w, int h, ctrl_t *parent)
{
 
ctrl_t *ctrl;
 
if( !parent )
return NULL;
 
ctrl = (ctrl_t*)malloc(size);
 
link_initialize(&ctrl->link);
list_initialize(&ctrl->child);
 
ctrl->parent = parent;
 
ctrl->ctx = parent->ctx;
ctrl->font = parent->font;
ctrl->id = id;
 
ctrl->rc.l = x;
ctrl->rc.t = y ;
 
ctrl->rc.r = x + w;
ctrl->rc.b = y + h;
 
ctrl->w = w;
ctrl->h = h;
 
list_append(&ctrl->link, &parent->child);
 
return ctrl;
};
 
 
int move_ctrl(ctrl_t *ctrl, int x, int y, int w, int h)
{
rect_t rc;
rc.l = x;
rc.t = y;
rc.r = w;
rc.b = h;
 
send_message(ctrl, MSG_POSCHANGING, 0, &rc);
 
ctrl->rc.l = rc.l;
ctrl->rc.t = rc.t;
ctrl->rc.r = rc.l + rc.r;
ctrl->rc.b = rc.t + rc.b;
ctrl->w = rc.r;
ctrl->h = rc.b;
 
send_message(ctrl, MSG_POSCHANGE, 0, &rc);
 
return 1;
};
 
 
 
/*
*
*
*
*
*
*
*
*
*/
 
int def_ctrl_proc(ctrl_t *ctrl, uint32_t msg, uint32_t arg1, uint32_t arg2)
{
switch( msg )
{
 
};
 
return 0;
}
 
/*
*
*
*
*
*
*
*
*
*/
 
 
static void scroller_on_draw(scroller_t *scrl)
{
if(scrl->btn_up)
send_message((ctrl_t*)scrl->btn_up, MSG_DRAW, 0, 0);
 
if(scrl->btn_down)
send_message((ctrl_t*)scrl->btn_down, MSG_DRAW, 0, 0);
 
if(scrl->thumb)
send_message((ctrl_t*)scrl->thumb, MSG_DRAW, 0, 0);
 
if(scrl->tl_rect.t != scrl->tl_rect.b)
px_fill_rect(scrl->ctrl.ctx, &scrl->tl_rect, 0xFFE1D8D0);
 
if(scrl->br_rect.t != scrl->br_rect.b)
px_fill_rect(scrl->ctrl.ctx, &scrl->br_rect, 0xFFE1D8D0);
}
 
static void scroller_on_ownerdraw(scroller_t *scrl, ctrl_t *child)
{
typedef struct
{
ctrl_t ctrl;
 
uint32_t state;
 
char *caption;
int capt_len;
}button_t;
 
button_t *btn;
color_t color = 0xFFD7D7D7;
char t = (char)child->id;
rect_t rc;
 
switch(child->id)
{
case ID_SCROLLER_UP:
case ID_SCROLLER_DOWN:
btn = (button_t*)child;
if(btn->state & bPressed)
color = 0xFFB0B0B0;
else if(btn->state & bHighlight)
color = 0xFFE7E7E7;
 
rc = btn->ctrl.rc;
px_fill_rect(btn->ctrl.ctx, &rc, color);
rc.l+= 3;
rc.t+= 5;
draw_text_ext(btn->ctrl.ctx, sym_font, &t, 1, &rc, 0xFF000000);
break;
 
case ID_SCROLLER_THUMB:
btn = (button_t*)child;
color = 0xFFB0B0B0;
if(btn->state & bPressed)
color = 0xFF707070;
else if(btn->state & bHighlight)
color = 0xFF909090;
 
rc = btn->ctrl.rc;
px_fill_rect(btn->ctrl.ctx, &rc, color);
}
};
 
static void scroller_update_layout(scroller_t *scrl)
{
 
// th_size = scrl->pix_range*scrl->page_size/
// (scrl->max_range-scrl->min_range);
 
// if(th_size > scrl->pix_range)
// th_size = scrl->pix_range;
 
scrl->tl_rect.l = scrl->ctrl.rc.l;
scrl->br_rect.l = scrl->ctrl.rc.l;
 
scrl->tl_rect.r = scrl->ctrl.rc.r;
scrl->br_rect.r = scrl->ctrl.rc.r;
 
scrl->tl_rect.t = scrl->btn_up->rc.b;
scrl->tl_rect.b = scrl->thumb->rc.t;
 
scrl->br_rect.t = scrl->thumb->rc.b;
scrl->br_rect.b = scrl->btn_down->rc.t;
 
scrl->pix_range = scrl->ctrl.h - 40 - 20;
};
 
static void scroller_on_poschange(scroller_t *scrl, rect_t *pos)
{
move_ctrl(scrl->btn_up, pos->l, pos->t, pos->r, pos->r);
move_ctrl(scrl->btn_down, pos->l, pos->t+pos->b-pos->r, pos->r, pos->r);
move_ctrl(scrl->thumb, pos->l, pos->t+pos->r, pos->r, pos->r);
 
scroller_update_layout(scrl);
scroller_on_draw(scrl);
};
 
static void scroller_on_command(scroller_t *ctrl, int id, ctrl_t *child, int notify)
{
scroller_t *scrl = (scroller_t*)ctrl;
int thumb_pos = scrl->thumb_pos;
 
switch(id)
{
case ID_SCROLLER_UP:
if(scrl->thumb_pos > scrl->min_range)
scrl->thumb_pos--;
printf("scroll up\n");
break;
case ID_SCROLLER_DOWN:
if(scrl->thumb_pos < scrl->max_range)
scrl->thumb_pos++;
printf("scroll down\n");
break;
};
 
if(thumb_pos != scrl->thumb_pos)
{
rect_t rc = scrl->thumb->rc;
int offset = scrl->pix_range*scrl->thumb_pos;
offset /= scrl->max_range - scrl->min_range;
rc.t = scrl->ctrl.rc.t + scrl->btn_up->h + offset;
rc.r = scrl->thumb->w;
rc.b = scrl->thumb->h;
move_ctrl(scrl->thumb, rc.l, rc.t, rc.r, rc.b);
scroller_update_layout(scrl);
scroller_on_draw(scrl);
}
}
 
int scroller_proc(ctrl_t *ctrl, uint32_t msg, uint32_t arg1, uint32_t arg2)
{
scroller_t *scrl = (scroller_t*)ctrl;
 
switch( msg )
{
HANDLE_MSG(scrl, MSG_DRAW, scroller_on_draw);
HANDLE_MSG(scrl, MSG_COMMAND, scroller_on_command);
HANDLE_MSG(scrl, MSG_OWNERDRAW, scroller_on_ownerdraw);
HANDLE_MSG(scrl, MSG_POSCHANGE, scroller_on_poschange);
};
 
return 0;
};
 
 
scroller_t *create_scroller(uint32_t style, int id, int x, int y,
int w, int h, ctrl_t *parent)
{
scroller_t *scrl;
 
if( !parent )
return NULL;
 
scrl = create_control(sizeof(scroller_t), id, x, y, w, h, parent);
scrl->ctrl.handler = scroller_proc;
 
scrl->min_range = 0;
scrl->max_range = 100;
scrl->thumb_pos = 0;
scrl->page_size = 1;
 
scrl->btn_up = create_button(NULL, 1, ID_SCROLLER_UP, x, y, w, w, (ctrl_t*)scrl);
scrl->btn_down = create_button(NULL, 1, ID_SCROLLER_DOWN, x, y+h-w, w, w, (ctrl_t*)scrl);
scrl->thumb = create_button(NULL, 1, ID_SCROLLER_THUMB, x, w, w, w, (ctrl_t*)scrl);
 
scroller_update_layout(scrl);
 
return scrl;
};