#include "diawxgtk.h" #include #include using namespace std; class CLIST_MAP{ public: map lk; }; typedef map::iterator CLIST_MAP_IT; class MFORM_CLIST: public MFORM{ CLIST *cl; public: MFORM_CLIST(CLIST *_cl) : MFORM (_cl,"--SUBCL--"){ cl = _cl; } void hmoveitems(int newpos){ MFORM::hmoveitems (newpos); if (cl->hoffset != hoffset){ cl->hoffset = hoffset; wxClientDC dc(cl); cl->drawhead(dc); } } void Event_OnPaint(wxEvent &e){ wxPaintDC dc (this); dc.SetBackground (*brush_white); dc.Clear(); MFORM::Real_OnPaint(dc); } void mouseevent(wxMouseEvent & event){ MFORM::mouseevent(event); } DECLARE_EVENT_TABLE() }; #ifndef PROTO_SKIP BEGIN_EVENT_TABLE(MFORM_CLIST, MFORM) EVT_PAINT(MFORM_CLIST::Event_OnPaint) EVT_LEFT_DOWN(MFORM_CLIST::mouseevent) EVT_MIDDLE_DOWN(MFORM_CLIST::mouseevent) EVT_RIGHT_DOWN(MFORM_CLIST::mouseevent) END_EVENT_TABLE() #endif PUBLIC CLIST::CLIST ( wxFORMBASE *_parent, const char *_id, int _nbcol, const char *_cols[]) : MFORM (_parent,_id) { lookup = new CLIST_MAP; sub = new MFORM_CLIST(this); stretch_mode = STRETCH_LOOK; sub->stretch_mode = STRETCH_LOOK; sub->setvscroll(); sub->background.brush = brush_white; int nbline = rem_getvarval ("vsize"); if (nbline == -1){ sub->max_height = 200; }else{ sub->max_height = ((int)GetCharHeight()+2)*nbline; } sub->max_width = 600; max_width = 2600; max_height = 2200; New_form(sub); Setweightlast (1,1); cols = NULL; hdispo = NULL; hsign = NULL; dcs = NULL; const char *pt = rem_getvar ("hid"); hid = NULL; if (pt != NULL) hid = strdup(pt); sethead (_nbcol,_cols); } PRIVATE void CLIST::freecols() { if (cols != NULL){ for (int i=0; ilk[id] = sub->nbc; for (int i=0; iNew_buttonfill (id,items[i],MFORM_OPTFLAT,ptdcs[i]); } sub->Newline(); } PUBLIC void CLIST::redolayout() { sub->Fit(); fit2top(); #if 0 if (layout_once && 0){ int w,h; sub->GetSize (&w,&h); BUG ("Clist dolayout"); //sub->dolayout (w,h,true); }else{ //gettop()->mainlayout(); } #endif } static void clist_mainlayout (void *data) { CLIST *cl = (CLIST*)data; cl->redolayout(); } /* Set the value of an existing line or add a new line */ PUBLIC void CLIST::Set_item (const char *id, const char *items[]) { bool redo=false; bool del = rem_getvarval("del")==1; // Are we deleting this record CLIST_MAP_IT it = lookup->lk.find (id); if (it == lookup->lk.end()){ // printf ("Set_item %s not found\n",id); if (!del) New_item (id,items); redo = true; }else{ int i = it->second; // printf ("Set_item %s, first=%s, i=%d, nbcol=%d\n",id,it->first.c_str(),i,nbcol); if (del){ int offset = nbcol+1; int offsety = sub->tbc[i]->height; // We must relocate the fields int newnbc = sub->nbc-offset; for (int j=i; jtbc[j]; for (int j=i; jtbc[j] = sub->tbc[j+offset]; sub->tbc[j]->y -= offsety; } // Ajust the lookup for (CLIST_MAP_IT t=lookup->lk.begin(); t!=lookup->lk.end(); t++){ if (t->second > it->second) t->second-= offset; } sub->nbc = newnbc; sub->drawitems (i,newnbc,true); // We must clear the end of the window int last = newnbc-offset; wxClientDC subdc(sub); subdc.SetPen (*pen_white); subdc.SetBrush (*brush_white); if (last < 0){ // We clear the window, no items anymore subdc.Clear(); }else{ // We clear after the last MFORM_C *c = sub->tbc[last]; int y = c->y + c->height; int w,h; sub->GetSize (&w,&h); subdc.DrawRectangle (0,y,w,h); } lookup->lk.erase(it); }else{ const char *dclist = rem_getvar("dcs"); DCNAME **ptdcs = dcs; DCNAME *tbdcs[nbcol]; if (dclist != NULL){ clist_parsedcs (dclist,tbdcs,nbcol); ptdcs = tbdcs; } for (int j=0; jtbc[i+j]; n->sets (items[j]); n->dcn = ptdcs[j]; wxCoord w,h; wxClientDC dc(this); dc.GetTextExtent (n->s,&w,&h); int wi = (int)w; if (n->width < wi) redo = true; } if (!redo){ sub->drawitems (i,i+nbcol,true); } } } if (redo){ revlayout = sub->revlayout; remadmin_regalive (clist_mainlayout,this); } } /* Initial and subsequent setup of the heading */ PUBLIC void CLIST::sethead (int _nbcol, const char *_cols[]) { freecols(); nbcol = _nbcol; cols = new char *[_nbcol]; const char *dclist = rem_getvar("dcs"); delete [] dcs; dcs = new DCNAME *[_nbcol]; if (dclist != NULL){ clist_parsedcs (dclist,dcs,_nbcol); }else{ for (int i=0; i<_nbcol; i++) dcs[i] = NULL; } const char *pt = rem_getvar ("hdispo"); if (pt != NULL){ free (hdispo); hdispo = strdup(pt); } pt = rem_getvar ("hsign"); if (pt != NULL){ free (hsign); hsign = strdup(pt); } wxClientDC dc(this); int maxh = 0; for (int i=0; i<_nbcol; i++){ const char *s = _cols[i]; cols[i] = strdup(s); wxCoord w,h; dc.GetTextExtent (s,&w,&h); int wi = (int)w+5; int hi = (int)h; sub->mincols[i] = wi + (hid != NULL ? 10 : 0); if (hi > maxh) maxh = hi; } marge_haut = maxh + 5; } PUBLIC void CLIST::mouseevent (wxMouseEvent & event) { if (hid != NULL && event.ButtonDown()){ int y = (int)event.m_y; if (y < heady){ int x = (int)event.m_x + hoffset; int start = 0; for (int i=0; icolwidth[i]; if (x >= start && x < start+width){ char tmp[10]; sprintf (tmp,"%d",i); report_button (hid,false,&event,tmp); break; } start += width; } } } } /* Draw the heading of the list and the decoration around the list. */ PUBLIC void CLIST::drawhead(wxDC &dc) { // Clear the header area dc.SetPen (*pen_back); dc.SetBrush (*brush_back); int cwidth,cheight; GetSize (&cwidth,&cheight); dc.DrawRectangle (0,0,cwidth,marge_haut); int x = 8 - hoffset; wxCoord w,h; dc.GetTextExtent ("WWW",&w,&h); int y = (int)h+2; heady = y; const char *pts = hsign != NULL ? hsign : "---------------------------"; for (int i=0; icolwidth[i]; int xw = x+width; int xw4 = xw-8; int x4 = x-4; // Draw the small icons at the end of the button if (*pts != '-'){ int px2 = xw4-2; // End int px1 = xw4-5; // Center int px0 = xw4-8; // Start int py0 = 3; int py1 = y-3; if (*pts == 'd'){ dc.DrawLine (px0,py0,px1,py1); dc.DrawLine (px2,py0,px1,py1); }else if (*pts == 'u'){ dc.DrawLine (px0,py1,px1,py0); dc.DrawLine (px2,py1,px1,py0); } } // Draw the edges of the button dc.DrawLine (x4,y,xw4,y); if (hid != NULL){ dc.DrawLine (xw4,y,xw4,0); dc.SetPen (*pen_light); dc.DrawLine (x4,y,x4,0); dc.DrawLine (x4,0,xw4,0); } x = xw; } } PUBLIC void CLIST::Event_OnPaint(wxPaintEvent &) { wxPaintDC dc(this); MFORM::Real_OnPaint(dc); drawhead(dc); } PUBLIC int CLIST::setcurfield ( const char *id_suffix, wxWindow *tbfocus[], int &nbfocus) { // fprintf (stderr,"CLIST curfield :%s:\n",id_suffix); int ret = -1; for (int i=0; inbc; i++){ MFORM_C *c = sub->tbc[i]; // fprintf (stderr,"clist cmp :%s: :%s:\n",c->id,id_suffix); if (strcmp(c->id,id_suffix)==0){ ret = 0; int w,h; sub->GetSize (&w,&h); if (sub->hscroll != NULL) h -= 20; // fprintf (stderr,"sub voffset %d h %d y %d\n",sub->voffset,h,c->y); int charh2 = (int)GetCharHeight()*2; if (c->y < 0){ sub->vmoveitems(sub->voffset+c->y); }else if (c->y + charh2 > h){ sub->vmoveitems (sub->voffset+c->y-h+charh2); } // fprintf (stderr,"sub voffset %d h %d y %d\n",sub->voffset,h,c->y); tbfocus[nbfocus++] = sub; tbfocus[nbfocus++] = this; break; } } return ret; } PUBLIC void CLIST::setval( const char *id, const char *vals[], SETVAL_INFO &info) { if (id[0] == '\0'){ // Changing the header sethead (atoi(vals[0]),vals+1); wxClientDC dc(this); drawhead(dc); }else{ Set_item (id,vals); } } PUBLIC void CLIST::stretch ( int new_width, int new_height) // new_height: Not supported yet // Only horizontally strechable items so far { fprintf (stderr,"CLIST::stretch %d\n",new_width); MFORM::stretch(new_width,new_height); } PUBLIC void CLIST::Fit() { sub->Fit(); MFORM::Fit(); } PUBLIC void CLIST::resizeitems ( int diffx, int diffy) { // fprintf (stderr,"CLIST::resizeitems %d %d\n",diffx,diffy); sub->resizeitems (diffx,diffy); int w,h; GetSize (&w,&h); SetSize (w+diffx,h+diffy); } #ifndef PROTO_SKIP BEGIN_EVENT_TABLE(CLIST, MFORM) EVT_PAINT(CLIST::Event_OnPaint) EVT_LEFT_DOWN(CLIST::mouseevent) EVT_MIDDLE_DOWN(CLIST::mouseevent) EVT_RIGHT_DOWN(CLIST::mouseevent) END_EVENT_TABLE() #endif