#include #include "diawxxt.h" #include #include "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->IntDrawLine (x0,y0,x1,y1); }else if (command == PROTO_Drawrect){ dc->IntDrawLine (x0,y0,x1,y0); dc->IntDrawLine (x0,y1,x1,y1); dc->IntDrawLine (x0,y0,x0,y1); dc->IntDrawLine (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){ dc->DrawEllipse (x0,y0,x1,y1,it->args[4],it->args[5]); }else if (command == 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) { 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) { 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 = (int)GetCharWidth() * len; } } 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 wxText *MFORM::New_string ( const char *_id, int len, const char *initval) { MFORM_C *m = alloc_mf(_id); m->sets(initval); wxText *ret = new wxText (this,NULL,NULL,initval,-1,-1,(int)(len*GetCharWidth())); m->c = ret; m->type = T_STRING; return ret; } PUBLIC VIRTUAL wxText *MFORM::New_password ( const char *_id, int) // len { MFORM_C *m = alloc_mf(_id); m->sets(""); wxText *ret = new wxText (this,NULL,NULL,"",-1,-1,-1,-1,wxTE_PASSWORD); m->c = ret; m->type = T_STRING; return ret; } PUBLIC VIRTUAL wxText *MFORM::New_string (int len, const char *initval) { return New_string ("",len,initval); } PUBLIC VIRTUAL wxMultiText *MFORM::New_text ( const char *_id, int cols, int rows) { MFORM_C *m = alloc_mf(_id); m->sets(""); rows = (rows+1)*(int)GetCharHeight(); cols = (cols+1)*(int)GetCharWidth(); #if 1 wxMultiText *ret = new TEXTAREA (this,cols,rows); #else wxMultiText *ret = new wxMultiText (this,NULL,NULL,"",-1,-1,cols,rows ,wxHSCROLL); #endif m->c = ret; m->type = T_TEXT; 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,NULL,NULL,val,minval,maxval,width); 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,NULL,range,-1,-1,width); 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; } PUBLIC void FORMBASE::report_button ( const char *button_id, bool dodump, wxMouseEvent *event, const char *extra) { int bstate = 0; int formx=0,formy=0; if (event != NULL){ if (event->ButtonDown(1)) bstate |= 1; if (event->ButtonDown(2)) bstate |= 2; if (event->ButtonDown(3)) bstate |= 4; if (event->controlDown) bstate |= 8; if (event->shiftDown) bstate |= 16; if (event->altDown) bstate |= 32; if (event->metaDown) bstate |= 64; // Record the absolution position of the mouse. This // will be reused by popup menu int x = (int)event->x; int y = (int)event->y; formx = x + hoffset; formy = y + voffset; ClientToScreen(&x,&y); rem_setlastmouse (x,y); } char path[300]; formbase_getabspath(this,path); remadmin_setcursor (cursor_wait); if (dodump){ getlogicaltop()->dump(); } fprintf (mform_fout,"action %s %s %d %d %d %s\n",path,button_id,bstate ,formx,formy,extra); fflush (mform_fout); } class MFORM_BUTTON: public wxButton{ public: bool dodump; /*~PROTOBEG~ MFORM_BUTTON */ public: MFORM_BUTTON (MFORM *_parent, const char *str, bool _dodump); MFORM_BUTTON (MFORM *_parent, wxBitmap *bitmap); /*~PROTOEND~ MFORM_BUTTON */ }; static void button_func (wxObject &o, wxCommandEvent &ev) { extern FILE *ftty; if (ftty != NULL){ fprintf (ftty,"button\n"); fflush (ftty); } MFORM_BUTTON *b = (MFORM_BUTTON*)&o; FORMBASE *p = (FORMBASE*)b->GetParent(); for (int i=0; inbc; i++){ MFORM_C *c = p->tbc[i]; if (c->c == b){ p->report_button (c->id,b->dodump,NULL,""); 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 MFORM_BUTTON::MFORM_BUTTON( MFORM *_parent, const char *str, bool _dodump) : wxButton (_parent,button_func,(char*)str) { dodump = _dodump; } PUBLIC MFORM_BUTTON::MFORM_BUTTON(MFORM *_parent, wxBitmap *bitmap) : wxButton (_parent,button_func,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); wxButton *ret = new MFORM_BUTTON(this,str,dodump); 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_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,NULL,NULL); 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->Number()-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; 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(FORMBASE *sub) { MFORM_C *m = alloc_mf(); m->c = sub; m->type = T_FORM; } PUBLIC VIRTUAL void MFORM::New_book(FORMBASE *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,NULL,(char*)str); 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 FORMBASE::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; 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); } } } PUBLIC void FORMBASE::drawitems (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 && 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){ DrawIcon (c->bitmap,c->x,c->y,TRUE); } } } } } /* Play the various drawing primitives recorded bu the application */ PUBLIC VIRTUAL void MFORM::do_drawing () { draw->draw(this,dc,hoffset,voffset); } PUBLIC VIRTUAL void MFORM::Real_OnPaint () { // fprintf (stderr,"MFORM::Real_OnPaint start :%s:\n",id); do_drawing(); drawitems (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; iDrawLine (0,i,20,i); } for (i=maxy+1; iDrawLine (0,i,20,i); } } dc->DrawRectangle (0,miny,20,w_height-40); dc->DrawRectangle (0,maxy,w_width,20); //g.setFont (new Font("helvetica",Font.BOLD,24)); //FontMetrics met = g.getFontMetrics(); int charh = (int)dc->GetCharHeight(); int len = strlen(sidetitle); int y = maxy - 3; dc->SetPen (pen_back); int limity = miny + charh-3; int diffy = maxy - miny; int htext = len * charh; if (htext < diffy){ y = maxy - (diffy - htext)/2; } for (int i=0; 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 VIRTUAL void MFORM::OnPaint () { //gettop()->record_onpaint(this); Real_OnPaint(); } /* 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.y; int x = (int)event.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; 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); target->timer = NULL; wxPostDelete (this); } PUBLIC void MFORM::OnEvent(wxMouseEvent & event) { int it = locate_butfill (event); if (it != -1){ report_button (tbc[it]->id,false,&event,""); animatebut (it,true); 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.y + voffset; int x = (int)event.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; } } } } } PUBLIC void MFORM::OnChar(wxKeyEvent &) { // Do not seem to be ever called. I guess this is for widget, not panels } PROTECTED Bool MFORM::OnCharHook(wxKeyEvent& event) { int ret = FALSE; long key = event.KeyCode(); 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.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; } } return ret; } PRIVATE void MFORM::distribute ( int start, int end, int nbfill, int diffx) { if (nbfill > 0){ int space = diffx/nbfill; int newx = 0; for (int i=start; itype == T_FILL){ newx += space; }else if (item->c != NULL){ int cw,ch; item->c->GetSize(&cw,&ch); item->c->SetSize (newx,0,-1,-1); 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 = (FORMBASE*)item->c; if (b->may_stretch()){ int cw,ch; item->c->GetSize(&cw,&ch); b->stretch (diffx+cw,ch); break; } } } } } // 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; for (int i=0; itype == T_NEWLINE){ distribute (start,i,nbfill,diffx); start = i+1; nbfill = 0; }else if (item->type == T_FILL){ nbfill++; } } distribute (start,nbc,nbfill,diffx); SetSize (new_width,-1); } } /* 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) { if (diffx == 0 && diffy == 0) return; MFORM_C *tbexp[nbc]; // Item we may expand horizontally or vertically int nbexp=0; int totalh = 0; int totalv = 0; for (int i=0; ic != NULL){ if (item->weightx > 0 || item->weighty > 0){ tbexp[nbexp++] = item; totalh += item->weightx; totalv += item->weighty; }else if (item->type == T_FORM || item->type == T_CLIST || item->type == T_BOOK){ // Collected for Formbutton so they can resize FORMBASE *b = (FORMBASE*)item->c; if (b->may_stretch()) tbexp[nbexp++] = item; } } } // fprintf (stderr,"MFORM::resizeitems :%s: %d %d %d\n",id,diffx,diffy,nbexp); for (int i=0; ic->GetSize (&w,&h); int partx = totalh == 0 ? 0 : diffx*item->weightx/totalh; int party = totalv == 0 ? 0 : diffy*item->weighty/totalv; if (item->type == T_FORM || item->type == T_COMBO || item->type == T_CLIST || item->type == T_SHEET || item->type == T_BOOK){ FORMBASE *b = (FORMBASE*)item->c; b->resizeitems (partx,party); }else{ item->c->SetSize(w+partx,h+party); } } int w,h; GetSize (&w,&h); dolayout(w+diffx,h+diffy,true); // int nw,nh; // GetSize (&nw,&nh); // fprintf (stderr,"resizeitems dolayout :%s: %d %d -> %d %d -> %d %d\n" // ,id,w,h,nw,nh,w+diffx,h+diffy); } PUBLIC void MFORM::getweight (int &w, int &h) { int totalh = 0, totalv = 0; for (int i=0; ic != 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; w = totalh; h = totalv; // fprintf (stderr,"getweight %d %d\n",totalh,totalv); }