#include "diawxxt.h" PUBLIC PAGEPAD::PAGEPAD(const char *_title) { title = strdup(_title); start = 0; stop = 0; } PUBLIC PAGEPAD::~PAGEPAD() { free ((char*)title); } PUBLIC BOOK::BOOK (FORMBASE *_parent, const char *_id) : FORMBASE (_parent,_id) { nbpage = 0; nopage = 0; offsetx = offsety = b_offsety = 0; stretch_mode = STRETCH_LOOK; offpad = 0; scrollpad = false; focusid = NULL; const char *pt = rem_getvar ("focus"); if (pt != NULL){ focusid = strdup(pt); } } PUBLIC BOOK::~BOOK() { free (focusid); } PUBLIC void BOOK::New_page (FORMBASE *sub, const char *s) { PAGEPAD *pad = new PAGEPAD(s); pads[nbpage++] = pad; if (nbpage > 1){ pad->start = pads[nbpage-2]->stop; pad->stop = pad->start + getpadwidth(nbpage-1); } MFORM_C *m = alloc_mf(); m->c = sub; m->type = T_FORM; } PUBLIC MFORM *BOOK::New_form (const char *s) { pads[nbpage++] = new PAGEPAD(s); MFORM *ret = new MFORM (this,""); MFORM_C *m = alloc_mf(); m->c = ret; m->type = T_FORM; return ret; } PRIVATE void BOOK::drawsel ( wxDC *dc, int no, bool select, int offsetx, // The pad is drawn offsetx before (scrolled) int maxx) // The pad must not go further than maxx { // The selected pad has a double edge because it is on // top while the non selected ones have a single edge // which shows that they are lower int x0 = pads[no]->start+1 - offsetx; int x1 = x0 + 3; int x3 = pads[no]->stop - offsetx; int x2 = x3 - 3; if (x0 >= 0 && x0 < maxx){ if (x3 >= maxx){ dc->SetClippingRegion (x0,2,maxx-x0,offsety); } int y1 = offsety - 2; int y2 = offsety - 1; // Draw the tab darker or not if selected dc->SetBrush (select ? brush_back : brush_lightgray); dc->DrawRectangle (x1,2,x2-x1,y2-2); dc->SetPen (pen_black); dc->SetFont (font_prop); dc->DrawText (pads[no]->title,x1+3,15-GetCharHeight()); dc->SetPen (pen_white); dc->DrawLine (no == 0 ? x0 +1 : x0 ,y1,x1,y1); dc->DrawLine (x0,y2,x1,y2); dc->DrawLine (x1,2,x1,y1+1); dc->DrawLine (x1,2,x2,2); dc->DrawLine (x2,y1,x3,y1); dc->DrawLine (x2,y2,x3,y2); if (!select) dc->SetPen (pen_back); { int x1_1 = x1 - 1; dc->DrawLine (x1_1,2,x1_1,y1-1); dc->DrawLine (x1,1,x2,1); } dc->SetPen (pen_black); dc->DrawLine (x2,2,x2,y1); if (!select) dc->SetPen (pen_back); { int x2_1 = x2+1; dc->DrawLine (x2_1,2,x2_1,y1-1); } dc->SetPen (select ? pen_back : pen_white); dc->DrawLine (x1,y1,x2,y1); dc->DrawLine (x1,y2,x2,y2); if (x3 >= maxx){ dc->DestroyClippingRegion(); // Draw some black lines to show that the title is incomplete int switchpen = select ? 2 : 1; // Deeper shadow if selected for (int i=0; i<5; i++){ int xt = maxx - 5 + i; dc->SetPen (i < switchpen ? pen_black : pen_back); dc->DrawLine (xt,2,xt,4); dc->DrawLine (xt+1,5,xt+1,5); dc->DrawLine (xt,6,xt,6); dc->DrawLine (xt,7,xt+2,11); dc->DrawLine (xt+2,12,xt+3,offsety-3); } } } } #define SCROLLAREA 25 // 25 pixels at the end of the book for the arrow /* Make sure the selected page is visible */ PRIVATE void BOOK::setpadvisible (int no) { if (scrollpad){ int w_width,w_height; GetSize(&w_width,&w_height); while (1){ int offset = pads[offpad]->start; int lastx = w_width - SCROLLAREA; int start = pads[no]->start - offset; if (start < 0){ offpad--; }else if (start + 20 >= lastx){ offpad++; }else{ break; } } } } PRIVATE void BOOK::sendfocus (wxMouseEvent *ev) { if (focusid != NULL){ char tmp[10]; sprintf (tmp,"%d",nopage); report_button (focusid,false,ev,tmp); } } PUBLIC void BOOK::selpage (int no, wxMouseEvent *ev) { if (no != nopage){ int w_width,w_height; GetSize(&w_width,&w_height); int old_offpad = offpad; setpadvisible(no); if (old_offpad != offpad){ nopage = no; OnPaint(); }else{ tbc[nopage]->c->Show(FALSE); int offsetx = pads[offpad]->start; if (scrollpad) w_width -= SCROLLAREA; drawsel (dc,nopage,false,offsetx,w_width); nopage = no; tbc[nopage]->c->Show(TRUE); drawsel (dc,nopage,true,offsetx,w_width); } } sendfocus (ev); } PUBLIC void BOOK::selpage (FORMBASE *f) { for (int i=0; ic; if (page == f){ selpage (i,NULL); //nopage = i; //sendfocus(NULL); break; } } } PRIVATE bool BOOK::locatepad (int x, wxMouseEvent *ev) { x += pads[offpad]->start; for (int i=0; istart < x && x < pads[i]->stop){ selpage (i,ev); tbc[i]->c->SetFocus(); return true; } } return false; } PUBLIC void BOOK::OnEvent(wxMouseEvent & event) { if (event.ButtonDown()){ int y = (int)event.y; int x = (int)event.x; if (y < offsety){ int w_width,w_height; GetSize(&w_width,&w_height); if (scrollpad && x >= w_width-SCROLLAREA){ if (x > w_width - 15 && x < w_width-5){ int lastx = pads[nbpage-1]->stop - pads[offpad]->start; if (offpad < nbpage -1 && lastx >= w_width-20){ offpad++; OnPaint(); } }else if (x < w_width - 15){ if (offpad > 0){ offpad--; OnPaint(); } } }else{ locatepad(x,&event); } } } } PUBLIC void BOOK::OnPaint () { int w_width,w_height; GetSize(&w_width,&w_height); if (nbc > 0){ int y0 = offsety - 2; int y1 = y0 + 1; int lasty = b_offsety + 1; int lastx = w_width-4; // Erase to the end of the page dc->SetPen (pen_back); dc->SetBrush (brush_back); dc->DrawRectangle (0,0,w_width,18); dc->SetPen (pen_white); //dc->DrawLine (1,y0,3,y0); //dc->DrawLine (pads[nbpage-1]->stop-3,y0,lastx,y0); //dc->DrawLine (pads[nbpage-1]->stop-3,y1,lastx-1,y1); dc->DrawLine (1,y0,lastx,y0); dc->DrawLine (2,y1,lastx-1,y1); dc->DrawLine (1,y0,1,lasty); dc->DrawLine (2,y1,2,lasty); // Bottom shadow dc->SetPen (pen_black); dc->DrawLine (1,lasty,lastx,lasty); int lasty_1 = lasty - 1; dc->DrawLine (2,lasty_1,lastx,lasty_1); // Right shadow dc->DrawLine (lastx,lasty,lastx,y0+2); int lastx_1 = lastx - 1; dc->DrawLine (lastx_1,lasty,lastx_1,y0+2); int offsetx = pads[offpad]->start; int maxx = w_width; if (scrollpad){ // Draw two arrows (horizontal) to control the scroll // The arrows are not drawn if the corresponding movement // is not possible. maxx -= SCROLLAREA; bool last = pads[nbpage-1]->stop - pads[offpad]->start < maxx; dc->SetPen (pen_white); int offsety_1 = offsety-2; int offsety_2 = offsety_1/2; int w_width_1 = w_width-6; if (offpad > 0) dc->DrawLine (maxx,offsety_2,maxx+10,1); if (!last){ dc->DrawLine (maxx+11,1,w_width_1,offsety_2); dc->DrawLine (maxx+11,1,maxx+11,offsety_1); } dc->SetPen (pen_black); if (offpad > 0){ dc->DrawLine (maxx,offsety_2,maxx+10,offsety_1); dc->DrawLine (maxx+10,1,maxx+10,offsety_1); } if (!last) dc->DrawLine (maxx+11,offsety_1,w_width_1,offsety_2); } for (int i=0; iSetPen (pen_back); dc->SetBrush (brush_back); dc->DrawRectangle (0,0,w_width,w_height); } } /* Delete one sub-form */ PUBLIC void BOOK::delform(MFORM *fl) { pref_width = pref_height = -1; int pos = 0; bool found = false; int offset = 0; for (int i=0; ic; if (c->type == T_FORM && page == fl){ delete fl; delete c; offset = pads[i]->stop - pads[i]->start; delete pads[i]; pads[i] = NULL; if (nopage >= i && nopage > 0) nopage--; found = true; }else{ if (found) page->resetlayout(); tbc[pos] = tbc[i]; pads[pos] = pads[i]; pads[pos]->start -= offset; pads[pos]->stop -= offset; pos++; } } nbc = pos; nbpage = pos; if (nbpage > 0){ if (offpad >= nbpage) offpad = nbpage-1; }else{ offpad = 0; } OnPaint(); sendfocus (NULL); } PUBLIC void BOOK::stretch (int new_width, int new_height) { // fprintf (stderr,"BOOK::stretch %d %d\n",new_width,new_height); int diffx = new_width - pref_width; if (diffx < 0){ new_width = pref_width; diffx = 0; } int diffy = new_height - pref_height; if (diffy < 0){ new_height = pref_height; diffy = 0; } if (diffx > 0 || diffy > 0){ SetSize (-1,-1,new_width,new_height); } } PUBLIC void BOOK::resizeitems ( int diffx, int diffy) { // fprintf (stderr,"BOOK::resizeitems %d %d\n",diffx,diffy); for (int i=0; ic; if (c->type == T_FORM || c->type == T_BOOK){ page->resizeitems (diffx,diffy); }else{ fprintf (stderr,"Not resizing page ???\n"); } } int w,h; GetSize (&w,&h); SetSize(w+diffx,h+diffy); b_offsety += diffy; // fprintf (stderr,"BOOK::resizeitems end\n"); } PUBLIC void BOOK::getweight (int &w, int &h) { int totalh = 0, totalv = 0; for (int i=0; ic; if (c->type == T_FORM){ int w,h; page->getweight(w,h); if (w !=0) totalh = 1; if (h !=0) totalv = 1; } } w = totalh; h = totalv; // fprintf (stderr,"getweight %d %d\n",totalh,totalv); } PUBLIC bool BOOK::may_stretch() { bool ret = false; for (int i=0; ic; if (c->type == T_FORM){ if (page->may_stretch()){ ret = true; break; } } } return ret; }