#include "diawxxt.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,""){ cl = _cl; } void hmoveitems(int newpos){ MFORM::hmoveitems (newpos); if (cl->hoffset != hoffset){ cl->hoffset = hoffset; cl->drawhead(); } } void OnPaint(){ SetBackground (brush_white); dc->SetBackground (brush_white); dc->Clear(); MFORM::OnPaint(); } void OnEvent(wxMouseEvent & event){ #if 0 if (event.Entering()){ fprintf (stderr,"Entering\n"); SetFocus(); }else if (event.Leaving()){ fprintf (stderr,"Leaving\n"); } #endif //cl->OnEvent (event); MFORM::OnEvent(event); } }; PUBLIC CLIST::CLIST ( FORMBASE *_parent, const char *_id, int _nbcol, const char *_cols[]) : MFORM (_parent,_id) { lookup = new CLIST_MAP; sub = new MFORM_CLIST(this); sub->setvscroll(); 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() { if (layout_once && 0){ int w,h; sub->GetSize (&w,&h); sub->dolayout (w,h,true); }else{ gettop()->mainlayout(); } } 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; wxDC *subdc = sub->GetDC(); 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]; float w,h; 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) 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); } wxDC *dc = GetDC(); int maxh = 0; for (int i=0; i<_nbcol; i++){ const char *s = _cols[i]; cols[i] = strdup(s); float 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::OnEvent (wxMouseEvent & event) { if (hid != NULL && event.ButtonDown()){ int y = (int)event.y; if (y < heady){ int x = (int)event.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 = GetDC(); // 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; float w,h; dc->GetTextExtent ("WWW",&w,&h); int y = (int)h+2; heady = y; const char *pts = hsign != NULL ? hsign : "---------------------------"; for (int i=0; iSetPen (pen_black); dc->DrawText (cols[i],x,2); int width = sub->colwidth[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::OnPaint() { MFORM::OnPaint(); drawhead(); } 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); drawhead(); }else{ Set_item (id,vals); } } PUBLIC void CLIST::stretch ( int new_width, int) // new_height: Not supported yet // Only horizontally strechable items so far { // fprintf (stderr,"CLIST::stretch %d\n",new_width); } 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); }