#include #include "diawxgtk.h" #include "../diawxxt/protowx.h" /* Return the optional parameter id or "" */ static const char *mform_getoptid() { const char *id = rem_getvar("id"); if (id == NULL) id = ""; return id; } class MFORM_TIMER: public wxTimer{ public: MFORM *target; int but; /*~PROTOBEG~ MFORM_TIMER */ public: MFORM_TIMER (MFORM *_target, int _but); private: void Notify (void); public: /*~PROTOEND~ MFORM_TIMER */ }; struct MFORM_DRAW_ITEM { int command; char *s; int args[20]; int nbarg; DCNAME *dcn; // Optional drawing context }; // Manage the drawing of primitives class MFORM_DRAW{ MFORM_DRAW_ITEM *tb; int maxtb; int nb; /*~PROTOBEG~ MFORM_DRAW */ public: MFORM_DRAW (void); void add (int command, const char *s, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7); void add (int command, int args[], int nbarg); void draw (MFORM *win, wxDC&dc, int hoffset, int voffset); private: void grow (void); public: ~MFORM_DRAW (void); /*~PROTOEND~ MFORM_DRAW */ }; PUBLIC MFORM_DRAW::MFORM_DRAW() { maxtb = nb = 0; tb = NULL; } PUBLIC MFORM_DRAW::~MFORM_DRAW() { for (int i=0; inbarg = 0; it->command = command; it->s = NULL; if (s != NULL) it->s = strdup(s); it->args[0] = arg0; it->args[1] = arg1; it->args[2] = arg2; it->args[3] = arg3; it->args[4] = arg4; it->args[5] = arg5; it->args[6] = arg6; it->args[7] = arg7; it->dcn = defs_getvardc (); } PUBLIC void MFORM_DRAW::add( int command, int args[], int nbarg) { grow(); MFORM_DRAW_ITEM *it = tb+nb++; if (nbarg > 20){ fprintf (stderr,"Too many argument (max 20) for drawing command %d\n",command); nbarg = 20; } it->command = command; it->nbarg = nbarg; memcpy (it->args,args,nbarg*sizeof(int)); } PUBLIC void MFORM_DRAW::draw( MFORM *win, wxDC &dc, int hoffset, int voffset) { for (int i=0; idcn,dc); int x0 = it->args[0] - hoffset; int y0 = it->args[1] - voffset; int x1 = it->args[2] - hoffset; int y1 = it->args[3] - voffset; int command = it->command; if (command == PROTO_Drawline){ dc.DrawLine (x0,y0,x1,y1); }else if (command == PROTO_Drawrect){ dc.DrawLine (x0,y0,x1,y0); dc.DrawLine (x0,y1,x1,y1); dc.DrawLine (x0,y0,x0,y1); dc.DrawLine (x1,y0,x1,y1); }else if (command == PROTO_Fillrect){ dc.DrawRectangle (x0,y0,x1,y1); }else if (command == PROTO_Drawarc){ dc.DrawArc (x0,y0,x1,y1,it->args[4],it->args[5]); }else if (command == PROTO_Fillarc){ BUG ("mform.cc: drawellipse"); //dc.DrawEllipse (x0,y0,x1,y1,it->args[4],it->args[5]); }else if (command == PROTO_Clear){ BUG ("mform.cc: PROTO_Clear"); //win->SetBackground (dc.GetBrush()); //win->SetPen (dc.GetPen()); dc.SetBackground (dc.GetBrush()); //win->background.brush = dc.GetBrush(); //win->background.pen = dc.GetPen(); dc.Clear(); }else if (command == PROTO_Drawtext){ dc.DrawText (it->s,x0,y0); }else if (command == PROTO_Fillpolygon){ wxPoint pts[10]; int nopt=0; for (int i=0; inbarg; i+=2,nopt++){ pts[nopt].x = it->args[i] - hoffset; pts[nopt].y = it->args[i+1] - voffset; } dc.DrawPolygon(nopt, pts); } } defs_resetdc (dc); } PUBLIC MFORM_C::MFORM_C(const char *_id) { weightx = weighty = 0; h_align = ' '; v_align = 't'; is_hcontrib = true; v_cells = h_cells = 1; s = NULL; c = NULL; id = strdup(_id); type = T_UNKNOWN; pref_width = pref_height = -1; width = height = 0; homemade = false; radio = NULL; dcn = NULL; options = 0; bitmap = NULL; x = y = 0; } PUBLIC void MFORM_C::sets (const char *str) { free (s); s = strdup(str); } PUBLIC MFORM_C::~MFORM_C() { free (id); free (s); delete radio; } PUBLIC MFORM::~MFORM() { free (dispstr); //reset(); free (sidetitle); delete timer; delete draw; for (int i=0; i 0){ ret = tbc[nbc-1]; } return ret; } PUBLIC void MFORM::record_draw( int command, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7) { draw->add (command,NULL,arg0,arg1,arg2,arg3,arg4,arg5,arg6,arg7); } PUBLIC void MFORM::record_draw( int command, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5) { draw->add (command,NULL,arg0,arg1,arg2,arg3,arg4,arg5,0,0); } PUBLIC void MFORM::record_draw( int command, int arg0, int arg1, int arg2, int arg3) { draw->add (command,NULL,arg0,arg1,arg2,arg3,0,0,0,0); } PUBLIC void MFORM::record_draw( int command, int arg0, int arg1, const char *s) { draw->add (command,s,arg0,arg1,0,0,0,0,0,0); } PUBLIC void MFORM::record_draw( int command, int tb[], int nbarg) { draw->add (command,tb,nbarg); } /* Copy one area of the window to another area (of the same window) */ PUBLIC void MFORM::blit( int from_x0, int from_y0, int from_x1, int from_y1, int to_x, int to_y) { wxClientDC dc(this); dc.Blit (from_x0,from_y0,from_x1,from_y1,&dc,to_x,to_y,0); } /* Set a clipping region and redraw the window */ PUBLIC void MFORM::drawclip ( int x0, int y0, int x1, int y1) { wxClientDC dc(this); dc.SetClippingRegion (x0,y0,x1-x0,y1-y0); OnPaint(); dc.DestroyClippingRegion(); } PUBLIC VIRTUAL void MFORM::Newline() { MFORM_C *m = alloc_mf(); m->type = T_NEWLINE; } // Affect the colspan and rowspan of the previously added dialog item PUBLIC void MFORM::Dispolast( char h_align, // Horizontal disposition 'l', 'c', 'r' int h_cells, char v_align, // Vertical disposition 't', 'c', 'b' int v_cells) { MFORM_C *m = getlastc(); if (m != NULL){ m->h_align = h_align; if (h_cells > 10){ fprintf (stderr,"Warning; MFORM::Dispolast h_cells = %d > 10\n",h_cells); h_cells = 10; } m->h_cells = h_cells; m->v_align = v_align; m->v_cells = v_cells; } } // Affect the weight (resizing importance) of the previously added item // wx and wy are number >= 0. They are meaningless, except the // available space will be given to dialog items according to their // relative weight. A fixed item has 0,0 PUBLIC void MFORM::Setweightlast(int wx, int wy) { MFORM_C *m = getlastc(); if (m != NULL){ m->weightx = wx; m->weighty = wy; } } PUBLIC VIRTUAL void MFORM::New_label(const char *str) { MFORM_C *m = alloc_mf(mform_getoptid()); m->type = T_LABEL; m->homemade = true; m->sets(str); m->dcn = defs_getvardc (); Dispolast (' ',1,'c',1); const char *look = rem_getvar ("look"); if (look != NULL){ if (strcmp(look,"3d")==0){ m->options = MFORM_OPT3D; } } int len = rem_getvarval ("len"); if (len != -1){ m->pref_width = GetCharWidth() * len*3/4; } } PUBLIC VIRTUAL void MFORM::New_richtext(const char *str) { MFORM_C *m = alloc_mf(mform_getoptid()); m->type = T_RICHTEXT; m->homemade = true; m->sets(str); m->dcn = defs_getvardc (); } #if 0 PUBLIC VIRTUAL wxLabel *MFORM::New_wlabel(const char *str) { MFORM_C *m = alloc_mf(); wxLabel *ret = new wxLabel (str); m->c = ret; return ret; } #endif PUBLIC VIRTUAL wxTextCtrl *MFORM::New_string ( const char *_id, int len, const char *initval) { MFORM_C *m = alloc_mf(_id); m->sets(initval); int width = len * GetCharWidth()*3/4; wxTextCtrl *ret = new wxTextCtrl (this,-1,initval,wxDefaultPosition ,wxSize(width,-1)); //GetSizer()->Add (ret); ret->SetSizeHints (width,-1); m->c = ret; m->type = T_STRING; return ret; } PUBLIC VIRTUAL wxTextCtrl *MFORM::New_password ( const char *_id, int len) { MFORM_C *m = alloc_mf(_id); m->sets(""); int width = len * GetCharWidth()*3/4; wxTextCtrl *ret = new wxTextCtrl (this,-1,"",wxDefaultPosition ,wxSize(width,-1) ,wxTE_PASSWORD); ret->SetSizeHints (width,-1); m->c = ret; m->type = T_STRING; return ret; } PUBLIC VIRTUAL wxTextCtrl *MFORM::New_string (int len, const char *initval) { return New_string ("",len,initval); } PUBLIC VIRTUAL wxTextCtrl *MFORM::New_text ( const char *_id, int cols, int rows) { MFORM_C *m = alloc_mf(_id); m->sets(""); rows = (rows+1)*GetCharHeight(); cols = (cols+1)*GetCharWidth()*3/4; wxTextCtrl *ret = new TEXTAREA (this,cols,rows); m->c = ret; m->type = T_TEXT; m->weightx = m->weighty = 1; return ret; } PUBLIC VIRTUAL wxHTML *MFORM::New_html ( const char *_id, int cols, int rows) { MFORM_C *m = alloc_mf(_id); m->sets(""); rows = (rows+1)*GetCharHeight(); cols = (cols+1)*GetCharWidth()*3/4; wxHTML *ret = new wxHTML (this,cols,rows); m->c = ret; m->type = T_HTML; m->weightx = m->weighty = 1; return ret; } PUBLIC VIRTUAL wxTREE *MFORM::New_tree (const char *_id) { MFORM_C *m = alloc_mf(_id); m->sets(""); wxTREE *ret = new wxTREE (this,_id); m->c = ret; m->type = T_TREE; m->weightx = m->weighty = 1; return ret; } PUBLIC VIRTUAL wxSlider *MFORM::New_slider ( const char *_id, int width, int minval, int maxval, int val) { MFORM_C *m = alloc_mf(_id); wxSlider *ret = new wxSlider (this,-1,val,minval,maxval ,wxDefaultPosition,wxSize(width,-1)); m->c = ret; m->type = T_SLIDER; return ret; } PUBLIC VIRTUAL wxGauge *MFORM::New_gauge ( const char *_id, int width, int range, int val) { MFORM_C *m = alloc_mf(_id); wxGauge *ret = new wxGauge (this,-1,range,wxDefaultPosition ,wxSize(width,-1)); ret->SetValue (val); m->c = ret; m->type = T_GAUGE; return ret; } PUBLIC VIRTUAL void MFORM::Skip (int n) { MFORM_C *m = alloc_mf(); m->type = T_SKIP; m->h_cells = n; } PUBLIC VIRTUAL void MFORM::Fill () { MFORM_C *m = alloc_mf(); m->type = T_FILL; } PUBLIC VIRTUAL void MFORM::New_hline (const char *s) { MFORM_C *m = alloc_mf(); m->c = new HLINE (this,s); m->type = T_HLINE; Dispolast ('l',1,'c',1); } PUBLIC VIRTUAL void MFORM::New_hline () { New_hline (NULL); } PUBLIC VIRTUAL void MFORM::New_vline () { MFORM_C *m = alloc_mf(); m->type = T_VLINE; } int mform_mev2state(const wxMouseEvent &ev) { int bstate = 0; if (ev.ButtonDown(1)) bstate |= 1; if (ev.ButtonDown(2)) bstate |= 2; if (ev.ButtonDown(3)) bstate |= 4; if (ev.m_controlDown) bstate |= 8; if (ev.m_shiftDown) bstate |= 16; if (ev.m_altDown) bstate |= 32; if (ev.m_metaDown) bstate |= 64; return bstate; } PUBLIC void wxFORMBASE::report_button ( const char *button_id, bool dodump, wxMouseEvent *event, const char *extra, int cheaty) // ClientToScreen is odd // and we correct it based on the type of input { int bstate = 0; int formx=0,formy=0; if (event != NULL){ bstate = mform_mev2state(*event); // Record the absolution position of the mouse. This // will be reused by popup menu int x = (int)event->m_x; int y = (int)event->m_y; formx = x + hoffset; formy = y + voffset; ClientToScreen(&x,&y); y += cheaty; // BUG TRICK clienttoscreen does not work rem_setlastmouse (x,y); } char path[300]; formbase_getabspath(this,path); remadmin_setcursor (cursor_wait); if (dodump){ getlogicaltop()->dump(); } //fprintf (stderr,"action %s %s %d %d %d %s\n",path,button_id,bstate // ,formx,formy,extra); fprintf (mform_fout,"action %s %s %d %d %d %s\n",path,button_id,bstate ,formx,formy,extra); fflush (mform_fout); } PUBLIC void wxFORMBASE::report_button ( const char *button_id, bool dodump, wxMouseEvent *event, const char *extra) { report_button (button_id,dodump,event,extra,-45); } class MFORM_BUTTON: public wxButton{ public: bool dodump; /*~PROTOBEG~ MFORM_BUTTON */ public: MFORM_BUTTON (MFORM *_parent, const char *str, bool _dodump, int width); void func (wxMouseEvent&ev); /*~PROTOEND~ MFORM_BUTTON */ DECLARE_EVENT_TABLE() }; static void button_func (wxButton *b, bool dodump, wxMouseEvent &ev) { extern FILE *ftty; if (ftty != NULL){ fprintf (ftty,"button\n"); fflush (ftty); } wxFORMBASE *p = (wxFORMBASE*)b->GetParent(); for (int i=0; inbc; i++){ MFORM_C *c = p->tbc[i]; if (c->c == b){ p->report_button (c->id,dodump,&ev,"",0); int x,y,w,h; b->GetPosition (&x,&y); b->GetSize (&w,&h); y += h; p->ClientToScreen(&x,&y); rem_setlastmouse (x,y); break; } } } PUBLIC void MFORM_BUTTON::func (wxMouseEvent &ev) { button_func(this,dodump,ev); } #ifndef PROTO_SKIP BEGIN_EVENT_TABLE(MFORM_BUTTON, wxButton) EVT_LEFT_DOWN(MFORM_BUTTON::func) END_EVENT_TABLE() BEGIN_EVENT_TABLE(MFORM, wxPanel) EVT_PAINT(MFORM::Event_OnPaint) EVT_LEFT_DOWN(MFORM::mouseevent) EVT_MIDDLE_DOWN(MFORM::mouseevent) EVT_RIGHT_DOWN(MFORM::mouseevent) EVT_MOTION(MFORM::mouseevent) EVT_CHAR(MFORM::keyevent) EVT_SCROLL(MFORM::vscroll_func) END_EVENT_TABLE() #endif class MFORM_BITMAP_BUTTON: public wxBitmapButton{ public: bool dodump; /*~PROTOBEG~ MFORM_BITMAP_BUTTON */ public: MFORM_BITMAP_BUTTON (MFORM *_parent, wxBitmap *bitmap); void func (wxMouseEvent&ev); /*~PROTOEND~ MFORM_BITMAP_BUTTON */ DECLARE_EVENT_TABLE() }; PUBLIC void MFORM_BITMAP_BUTTON::func (wxMouseEvent &ev) { button_func(this,dodump,ev); } #ifndef PROTO_SKIP BEGIN_EVENT_TABLE(MFORM_BITMAP_BUTTON, wxButton) EVT_LEFT_DOWN(MFORM_BITMAP_BUTTON::func) END_EVENT_TABLE() #endif PUBLIC MFORM_BUTTON::MFORM_BUTTON( MFORM *_parent, const char *str, bool _dodump, int width) : wxButton (_parent,-1,str) //,wxDefaultPosition,wxSize(width,-1)) { //SetSize(width,-1); //SetSizeHints(width,-1); dodump = _dodump; } PUBLIC MFORM_BITMAP_BUTTON::MFORM_BITMAP_BUTTON(MFORM *_parent, wxBitmap *bitmap) : wxBitmapButton (_parent,-1,*bitmap) { dodump = rem_getvarval("dump")==1; } PUBLIC VIRTUAL wxButton *MFORM::New_button( const char *_id, bool dodump, const char *str) { MFORM_C *m = alloc_mf(_id); int width = strlen(str)*GetCharWidth(); wxButton *ret = new MFORM_BUTTON(this,str,dodump,width); //GetSizer()->Add (ret); m->c = ret; m->type = T_BUTTON; return ret; } PUBLIC VIRTUAL void MFORM::New_buttonfill( const char *_id, const char *str, int options, DCNAME *dc) { MFORM_C *m = alloc_mf(_id); m->homemade = true; m->sets (str); m->type = T_BUTTONFILL; m->options = options; m->dcn = dc; } PUBLIC VIRTUAL wxButton *MFORM::New_button( const char *_id, wxBitmap *bitmap) { MFORM_C *m = alloc_mf(_id); wxButton *ret = new MFORM_BITMAP_BUTTON(this,bitmap); m->c = ret; m->type = T_BUTTONXPM; return ret; } PUBLIC VIRTUAL void MFORM::New_icon_xpm( wxBitmap *bitmap) { MFORM_C *m = alloc_mf(); //wxButton *ret = new wxButton(this,NULL,bitmap); //m->c = ret; m->homemade = true; m->bitmap = bitmap; m->type = T_ICON; } PUBLIC VIRTUAL wxButton *MFORM::New_button(const char *str) { return New_button ("",false,str); } /* Define an input area. Whenever the user click on one cell of the grid, a report is sent to the application */ PUBLIC void MFORM::Inputgrid ( const char *id, int x, // Upper left corner of the grid int y, int cellwidth, // Size of a cell int cellheight, int nbcellh, // Number of cell horizontally and vertically int nbcellv) { nbgrid++; grids = (INPUTGRID*)realloc(grids,nbgrid*sizeof(INPUTGRID)); INPUTGRID *g = grids + (nbgrid-1); g->id = strdup(id); g->x = x; g->y = y; g->cellwidth = cellwidth; g->cellheight = cellheight; g->nbcellh = nbcellh; g->nbcellv = nbcellv; g->track = rem_getvarval ("track")==1; g->lastcellx = -1; g->lastcelly = -1; } PUBLIC VIRTUAL COMBO *MFORM::New_choice(const char *_id, const char *val) { MFORM_C *m = alloc_mf (_id); COMBO *ret = new COMBO(this,val,-1,true); m->c = ret; m->sets (val); m->type = T_COMBO; return ret; } PUBLIC VIRTUAL void MFORM::New_choice_item( const char *_id, int no, const char *val1, const char *val2) { for (int i=0; itype == T_COMBO && strcmp(m->id,_id)==0){ COMBO *c = (COMBO*)m->c; c->setItem(no,val1,val2); break; } } } PUBLIC VIRTUAL wxListBox *MFORM::New_list( const char *_id, int, // nbvisible const char *val) { MFORM_C *m = alloc_mf (_id); wxListBox *ret = new wxListBox (this,-1); m->c = ret; m->sets(val); m->type = T_LIST; return ret; } PUBLIC VIRTUAL void MFORM::New_list_item(const char *_id, const char *val) { for (int i=0; itype == T_LIST && strcmp(m->id,_id)==0){ wxListBox *c = (wxListBox*)m->c; c->Append((char*)val); if (strcmp(m->s,val)==0){ //fprintf (stderr,"list :%s: :%s: %d %d\n",m->s,val,strcmp(m->s,val),c->Number()); // This code does not seem to work in wxXT c->SetSelection(c->GetCount()-1,TRUE); } break; } } } PUBLIC VIRTUAL CLIST *MFORM::New_clist( const char *_listid, int nbcol, const char *cols[]) { MFORM_C *m = alloc_mf (_listid); CLIST *ret = new CLIST (this,_listid,nbcol,cols); m->c = ret; m->type = T_CLIST; m->weightx = m->weighty = 1; return ret; } PUBLIC VIRTUAL void MFORM::New_clist_item( const char *_listid, const char *_itemid, const char *vals[]) { for (int i=0; itype == T_CLIST && strcmp(m->id,_listid)==0){ CLIST *c = (CLIST*)m->c; c->New_item(_itemid,vals); break; } } } PUBLIC VIRTUAL SHEET *MFORM::New_sheet( const char *_sheetid, int nbcol, const char *cols[]) { MFORM_C *m = alloc_mf (_sheetid); SHEET *ret = new SHEET (this,_sheetid,nbcol,cols); m->c = ret; m->type = T_SHEET; return ret; } PUBLIC VIRTUAL void MFORM::New_sheet_item( const char *_sheetid, int row, int column, const char *val) { for (int i=0; itype == T_SHEET && strcmp(m->id,_sheetid)==0){ SHEET *c = (SHEET*)m->c; c->New_item(row,column,val); break; } } } PUBLIC VIRTUAL COMBO *MFORM::New_combo( const char *_id, int len, const char *val) { MFORM_C *m = alloc_mf (_id); COMBO *ret = new COMBO(this,val,len,false); m->c = ret; m->sets (val); m->type = T_COMBO; return ret; } PUBLIC VIRTUAL void MFORM::New_combo_item( const char *_id, int no, const char *val1, const char *val2) { for (int i=0; itype == T_COMBO && strcmp(m->id,_id)==0){ COMBO *c = (COMBO*)m->c; c->setItem(no,val1,val2); break; } } } PUBLIC VIRTUAL void MFORM::New_form(wxFORMBASE *sub) { MFORM_C *m = alloc_mf(); m->c = sub; m->type = T_FORM; } PUBLIC VIRTUAL void MFORM::New_book(wxFORMBASE *sub) { MFORM_C *m = alloc_mf(); m->c = sub; m->type = T_BOOK; } PUBLIC VIRTUAL void MFORM::New_book(wxBOOK *sub) { MFORM_C *m = alloc_mf(); m->c = sub; m->type = T_BOOK; } PUBLIC VIRTUAL MFORM *MFORM::New_form(const char *_id) { MFORM_C *m = alloc_mf(_id); MFORM *ret = new MFORM(this,_id); m->c = ret; m->type = T_FORM; return ret; } PUBLIC VIRTUAL FORMBUTTON *MFORM::New_formbutton(const char *_id) { FORMBUTTON *ret = new FORMBUTTON (this,_id); New_form (ret); return ret; } PUBLIC VIRTUAL FORMBUTTON *MFORM::New_formbutton() { return New_formbutton (""); } PUBLIC VIRTUAL wxCheckBox *MFORM::New_checkbox( const char *_id, bool state, const char *str) { MFORM_C *m = alloc_mf(_id); wxCheckBox *ret = new wxCheckBox (this,-1,str,wxDefaultPosition ,wxDefaultSize,0); ret->SetValue (state); m->c = ret; m->type = T_CHECKBOX; return ret; } PUBLIC CHECKBOX_RADIO::CHECKBOX_RADIO ( int _instance, bool _state) { instance = _instance; state = _state; } PUBLIC void MFORM::New_radio( const char *_id, int instance, bool state, const char *str) { MFORM_C *m = alloc_mf(_id); m->type = T_RADIO; CHECKBOX_RADIO *ret = new CHECKBOX_RADIO (instance,state); m->radio = ret; m->homemade = true; m->sets (str); } PUBLIC MFORM_C* MFORM::getitem (int n) const { MFORM_C *ret = NULL; if (n >= 0 && n < nbc) ret = tbc[n]; return ret; } PUBLIC void MFORM::New_component (wxWindow *comp) { MFORM_C *m = alloc_mf(); m->c = comp; } PUBLIC void MFORM::setsidetitle (const char *s) { free (sidetitle); sidetitle = strdup(s); } /* Draw the shape of a button (the 3D effect) */ PROTECTED void wxFORMBASE::drawbutfill( int nobut, wxPen *pentop, wxPen *penbot, bool clear, bool anim) { MFORM_C *c = tbc[nobut]; int x = c->x; int y = c->y; int charh2 = (int)(2*GetCharHeight()); int topy = y + 1; // if (!IsExposed(x,topy,c->width,c->height)) return; int endx = x+c->width; int endy = y+charh2-2; int skipx = 0; wxClientDC dc(this); if ((c->options & MFORM_OPTFLAT) != 0){ if (clear){ if (anim){ dc.SetPen (*pen_back); dc.SetBrush (*brush_back); }else{ dc.SetPen (*pen_white); dc.SetBrush (*brush_white); } dc.DrawRectangle (x,topy,c->width,c->height); dc.SetPen (*pen_black); } }else{ if (clear){ dc.SetPen (*pen_back); dc.SetBrush (*brush_back); dc.DrawRectangle (x,topy,c->width,charh2); } dc.SetPen (*pentop); dc.DrawLine (x,topy,endx,topy); topy++; dc.DrawLine (x,topy,endx,topy); if (nobut > 0 && tbc[nobut-1]->type != T_BUTTONFILL){ dc.DrawLine (x,topy,x,endy); dc.DrawLine (x+1,topy,x+1,endy); skipx = 1; } dc.SetPen (*penbot); int lowy = endy - 1; dc.DrawLine (x+skipx,lowy,endx,lowy); lowy++; dc.DrawLine (x,lowy,endx,lowy); if (nobut < nbc-1 && tbc[nobut+1]->type != T_BUTTONFILL){ dc.DrawLine (endx,topy+1,endx,endy); dc.DrawLine (endx-1,topy+2,endx-1,endy); } } } PROTECTED void wxFORMBASE::drawitems (wxDC &dc, int start, int end, bool clear) { // fprintf (stderr,"drawitems :%s: %d %d %d\n",id,start,end,clear); dc.SetFont (*font_normal); { int charh2 = (int)(2*GetCharHeight()); int miny = -charh2; int ww,wh; GetClientSize (&ww,&wh); if (hscroll != NULL){ int hw,hh; hscroll->GetSize (&hw,&hh); wh -= hh; } int maxy = wh; // + charh2; for (int i=start; ihomemade,miny,c->y,maxy); if (c->homemade && c->y > miny && c->y < maxy){ int x = c->x; int y = c->y; dc.SetPen (*pen_black); if (c->type == T_LABEL){ dc.SetFont (*font_prop); defs_setdc (c->dcn,dc); if (clear){ dc.SetPen (*background.pen); dc.SetBrush (*background.brush); int charh = (int)dc.GetCharHeight(); dc.DrawRectangle (x,y,c->width,charh+2); dc.SetPen (*pen_black); } dc.DrawText (c->s,x+2,y+2); defs_resetdc (dc); }else if (c->type == T_RICHTEXT){ defs_setdc (c->dcn,dc); richtext_draw (c->s,x+2,y+4); defs_resetdc (dc); }else if (c->type == T_BUTTONFILL){ drawbutfill (i,pen_white,pen_black,clear,false); defs_setdc (c->dcn,dc); dc.DrawText (c->s,x+3,y+4); defs_resetdc (dc); }else if (c->type == T_RADIO){ drawradio_but (c); dc.DrawText (c->s,x+14,y+4); }else if (c->type == T_ICON){ dc.DrawBitmap (*c->bitmap,c->x,c->y,TRUE); } } } } } PUBLIC void wxFORMBASE::drawitems (int start, int end, bool clear) { wxClientDC dc(this); drawitems (dc,start,end,clear); } /* Play the various drawing primitives recorded bu the application */ PROTECTED void MFORM::do_drawing (wxDC &dc) { draw->draw(this,dc,hoffset,voffset); } PUBLIC void MFORM::do_drawing () { wxClientDC dc(this); do_drawing (dc); } PUBLIC VIRTUAL void MFORM::Real_OnPaint (wxDC &dc) { // fprintf (stderr,"MFORM::Real_OnPaint start :%s:\n",id); do_drawing(dc); drawitems (dc,0,nbc,false); if (sidetitle != NULL){ int w_width,w_height; GetSize (&w_width,&w_height); int miny = 20; int maxy = w_height - 20; dc.SetBrush (*brush_white); dc.SetPen (*pen_white); dc.DrawRectangle (0,0,20,miny); dc.DrawRectangle (0,maxy,20,20); if (false){ int i; for (i=1; i limity; i++, y -= charh){ static char tmp[2]={0,0}; tmp[0] = sidetitle[i]; dc.DrawText (tmp,1,y); } } // fprintf (stderr,"MFORM::Real_OnPaint end :%s:\n",id); } PUBLIC void MFORM::OnPaint () { wxClientDC dc (this); Real_OnPaint(dc); } PUBLIC void MFORM::Event_OnPaint (wxPaintEvent&) { wxPaintDC dc (this); int w,h; GetClientSize (&w,&h); // fprintf (stderr,"MFORM::onpaint :%s: %d %d\n",id,w,h); Real_OnPaint(dc); } /* Locate the homemade item which was clicked. Return NULL if none. */ PUBLIC int MFORM::locate_click (wxMouseEvent & event, int type) { int ret = -1; if (event.ButtonDown()){ int y = (int)event.m_y; int x = (int)event.m_x; for (int i=0; itype == type && x > c->x && x < c->x + c->width && y > c->y && y < c->y + c->height){ ret = i; break; } } } return ret; } /* Check if a Buttonfill was selected */ PUBLIC int MFORM::locate_butfill(wxMouseEvent & event) { return locate_click (event,T_BUTTONFILL); } PUBLIC void MFORM::animatebut (int it, bool down) { wxPen *pentop = pen_white; wxPen *penbot = pen_black; if (down){ pentop = pen_black; penbot = pen_white; } // Show some animation proving that the button was hit int left = it; wxClientDC dc(this); while (left >= 0){ MFORM_C *c = tbc[left]; if (c->type != T_BUTTONFILL) break; drawbutfill (left,pentop,penbot,true,down); defs_setdc (c->dcn,dc); dc.DrawText (c->s,c->x+3,c->y+4); left--; } int right = it+1; while (right < nbc){ MFORM_C *c = tbc[right]; if (c->type != T_BUTTONFILL) break; drawbutfill (right,pentop,penbot,true,down); defs_setdc (c->dcn,dc); dc.DrawText (c->s,c->x+3,c->y+4); right++; } defs_resetdc (dc); } PUBLIC MFORM_TIMER::MFORM_TIMER(MFORM *_target, int _but) { target = _target; but = _but; Start (50,true); } PRIVATE void MFORM_TIMER::Notify() { target->animatebut (but,false); // Timer are destroyed in the MFORM destructor or when a new // one is needed. } PUBLIC void MFORM::mouseevent(wxMouseEvent & event) { int it = locate_butfill (event); if (it != -1){ report_button (tbc[it]->id,false,&event,""); animatebut (it,true); delete timer; timer = new MFORM_TIMER (this,it); }else{ it = locate_click (event,T_RADIO); if (it != -1){ getlogicaltop()->processradio (tbc[it]); }else{ // Check the inputgrid int y = (int)event.m_y + voffset; int x = (int)event.m_x + hoffset; for (int i=0; ix + g->nbcellh*g->cellwidth; int lasty = g->y + g->nbcellv*g->cellheight; if (x >= g->x && y >= g->y && x < lastx && y < lasty){ // Ok, we are inside the grid if (event.ButtonDown()){ report_button (g->id,false,&event,""); }else if (g->track){ int cx = (x-g->x)/g->cellwidth; int cy = (y-g->y)/g->cellheight; if (g->lastcellx != cx || g->lastcelly != cy){ g->lastcellx = cx; g->lastcelly = cy; report_button (g->id,false,&event,""); } } break; }else if (g->lastcellx != -1 && g->track){ // We are leaving the grid, we must tell the application report_button (g->id,false,&event,""); g->lastcellx = g->lastcelly = -1; } } } } } PROTECTED void MFORM::keyevent(wxKeyEvent& event) { // int ret = FALSE; long key = event.GetKeyCode(); if (key == WXK_RETURN){ MAINFORM *mf = gettop(); const char *enteraction = mf->getenteraction(); if (enteraction != NULL){ char path[300]; formbase_getabspath(mf,path); remadmin_setcursor (cursor_wait); mf->dump(); fprintf (mform_fout,"action %s %s\n",path,enteraction); fflush (mform_fout); //ret = TRUE; } }else if (vscroll != NULL){ int viewstart,viewlength,objlength,pagelength; vscroll->GetValues(&viewstart, &viewlength, &objlength, &pagelength); int charh = (int)GetCharHeight(); // ret = TRUE; bool ctrl = event.m_controlDown; if (key == WXK_DOWN){ vmoveitems (voffset + charh); }else if (key == WXK_UP){ vmoveitems (voffset - charh); }else if (key == WXK_PRIOR){ int new_offset = voffset - pagelength; if (ctrl) new_offset = 0; vmoveitems (new_offset); }else if (key == WXK_NEXT){ int new_offset = voffset + pagelength; if (ctrl) new_offset = objlength-viewlength; vmoveitems (new_offset); }else{ // ret = FALSE; } } } PRIVATE void MFORM::distribute ( int start, int end, int nbfill, int diffx) { if (nbfill > 0){ int space = diffx/nbfill; //layout_debug (id,"distribute nbfill %d space %d\n",nbfill,space); int newx = 0; for (int i=start; itype == T_FILL){ item->width = space; newx += space; }else if (item->c != NULL){ int cw,ch; //int x,y; //item->c->GetPosition(&x,&y); item->c->GetSize(&cw,&ch); //layout_debug (id,"distribute SetSize newx %d cw %d x %d y %d\n",newx,cw,x,y); item->c->SetSize (newx,-1,-1,-1,0); //item->c->GetPosition(&x,&y); //layout_debug (id,"distribute2 x %d y %d\n",x,y); newx += cw; } } }else{ // Strech only one item on the line // One day, we will need a weight concept for (int i=start; itype == T_FORM || item->type == T_BOOK){ FORMBASE *b = item->getformbase(); if (b->may_stretch()){ int cw,ch; item->c->GetSize(&cw,&ch); b->stretch (diffx+cw,ch); break; } }else if (item->type == T_TEXT){ int cw,ch; item->c->GetSize(&cw,&ch); item->c->SetSize (diffx+cw,ch); } } } } // Enlarge a dialog so it fits a constraint PUBLIC void MFORM::stretch ( int new_width, int) // new_height: Not supported yet // Only horizontally strechable items so far { int diffx = new_width - pref_width; if (diffx > 0){ int start = 0; int nbfill = 0; SetSize (new_width,-1); for (int i=0; itype == T_NEWLINE){ distribute (start,i,nbfill,diffx); start = i+1; nbfill = 0; }else if (item->type == T_FILL){ nbfill++; } } //layout_debug (id,"stretch newwidth %d pref_width %d nbfill %d\n",new_width,pref_width,nbfill); distribute (start,nbc,nbfill,diffx); } } /* Enlarge the items of a dialog after the user has resized the window Use the standard strategy of the weights to distribute the available space to each components. For complex layout, it is much easier to redefine resizeitems(). */ PUBLIC void MFORM::resizeitems( int diffx, int diffy) { { int w,h; GetClientSize(&w,&h); layout_debug (id,"Start resizeitems %d %d %d %d\n",w,h,diffx,diffy); } if (diffx == 0 && diffy == 0) return; struct { MFORM_C *item; int noline; } tbexp[nbc]; // Item we may expand horizontally or vertically int nbexp=0; short unsigned int totalh[nbc]; memset (totalh,0,sizeof(totalh)); int totalv = 0; int noline = 0; for (int i=0; itype == T_NEWLINE){ noline++; }else if (item->c != NULL){ if (item->weightx > 0 || item->weighty > 0){ tbexp[nbexp].item = item; tbexp[nbexp++].noline = noline; }else if (item->type == T_FORM || item->type == T_CLIST || item->type == T_BOOK){ // Collected for Formbutton so they can resize FORMBASE *b = item->getformbase(); if (b->may_stretch()){ b->getweight(item->weightx,item->weighty); tbexp[nbexp].item = item; tbexp[nbexp++].noline = noline; } } totalh[noline] += item->weightx; totalv += item->weighty; } } //layout_debug (id,"MFORM::resizeitems %d %d %d -- %d %d\n",diffx,diffy,nbexp,totalh[0],totalv); for (int i=0; ic->GetSize (&w,&h); int partx = totalh_line == 0 ? 0 : diffx*item->weightx/totalh_line; int party = totalv == 0 ? 0 : diffy*item->weighty/totalv; item->c->SetSize(w+partx,h+party); if (0){ if (item->type == T_FORM || item->type == T_COMBO || item->type == T_CLIST || item->type == T_SHEET || item->type == T_BOOK){ FORMBASE *b = item->getformbase(); //fprintf (stderr,"resize sub %s %d %d\n",b->id,partx,party); b->resizeitems (partx,party); } } } int w,h; GetClientSize (&w,&h); wxSize sz; dolayout(w,h,true,sz); layout_debug (id,"resizeitems dolayout fin %d %d\n",w,h); } PUBLIC void MFORM::getweight (int &w, int &h) { int totalh = 0, totalv = 0; bool somefill = false; for (int i=0; itype == T_FILL){ somefill = true; }else if (item->c != NULL){ if (item->weightx > 0){ totalh += item->weightx; } if (item->weighty > 0){ totalv += item->weighty; } } } if (totalh == 0 && hscroll != NULL) totalh = 1; if (totalv == 0 && vscroll != NULL) totalv = 1; if (totalh == 0 && somefill) totalh = 1; w = totalh; h = totalv; // fprintf (stderr,"getweight %d %d\n",totalh,totalv); }