static LRESULT WINAPI swellFileSelectProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { const int maxPathLen = 2048; const char *multiple_files = "(multiple files)"; switch (uMsg) { case WM_CREATE: if (lParam) // swell-specific { SetWindowLong(hwnd,GWL_WNDPROC,(LPARAM)SwellDialogDefaultWindowProc); SetWindowLong(hwnd,DWL_DLGPROC,(LPARAM)swellFileSelectProc); SetWindowLongPtr(hwnd,GWLP_USERDATA,lParam); BrowseFile_State *parms = (BrowseFile_State *)lParam; if (parms->caption) SetWindowText(hwnd,parms->caption); SWELL_MakeSetCurParms(1,1,0,0,hwnd,false,false); SWELL_MakeButton(0, parms->mode == BrowseFile_State::OPENDIR ? "Choose directory" : parms->mode == BrowseFile_State::SAVE ? "Save" : "Open", IDOK,0,0,0,0, 0); SWELL_MakeButton(0, "Cancel", IDCANCEL,0,0,0,0, 0); HWND edit = SWELL_MakeEditField(0x100, 0,0,0,0, 0); HWND dir = SWELL_MakeCombo(0x103, 0,0,0,0, CBS_DROPDOWNLIST); HWND list = SWELL_MakeControl("",0x104,"SysListView32",LVS_REPORT|LVS_SHOWSELALWAYS| (parms->mode == BrowseFile_State::OPENMULTI ? 0 : LVS_SINGLESEL)| LVS_OWNERDATA|WS_BORDER|WS_TABSTOP,0,0,0,0,0); if (list) { LVCOLUMN c={LVCF_TEXT|LVCF_WIDTH, 0, 280, (char*)"Filename" }; ListView_InsertColumn(list,0,&c); c.cx = 120; c.pszText = (char*) "Size"; ListView_InsertColumn(list,1,&c); c.cx = 140; c.pszText = (char*) "Date"; ListView_InsertColumn(list,2,&c); } HWND extlist = (parms->extlist && *parms->extlist) ? SWELL_MakeCombo(0x105, 0,0,0,0, CBS_DROPDOWNLIST) : NULL; if (extlist) { const char *p = parms->extlist; while (*p) { const char *rd=p; p += strlen(p)+1; if (!*p) break; int a = SendMessage(extlist,CB_ADDSTRING,0,(LPARAM)rd); SendMessage(extlist,CB_SETITEMDATA,a,(LPARAM)p); p += strlen(p)+1; } SendMessage(extlist,CB_SETCURSEL,0,0); } SWELL_MakeLabel(-1,parms->mode == BrowseFile_State::OPENDIR ? "Directory: " : "File:",0x101, 0,0,0,0, 0); if (BFSF_Templ_dlgid && BFSF_Templ_dlgproc) { HWND dlg = SWELL_CreateDialog(BFSF_Templ_reshead, BFSF_Templ_dlgid, hwnd, BFSF_Templ_dlgproc, 0); if (dlg) SetWindowLong(dlg,GWL_ID,0x102); BFSF_Templ_dlgproc=0; BFSF_Templ_dlgid=0; } SWELL_MakeSetCurParms(1,1,0,0,NULL,false,false); if (edit && dir) { char buf[maxPathLen]; const char *filepart = ""; if (parms->initialfile && *parms->initialfile && *parms->initialfile != '.') { lstrcpyn_safe(buf,parms->initialfile,sizeof(buf)); char *p = (char *)WDL_get_filepart(buf); if (p > buf) { p[-1]=0; filepart = p; } } else if (parms->initialdir && *parms->initialdir) { lstrcpyn_safe(buf,parms->initialdir,sizeof(buf)); } else getcwd(buf,sizeof(buf)); SetWindowText(edit,filepart); SendMessage(hwnd, WM_USER+100, 0x103, (LPARAM)buf); } SetWindowPos(hwnd,NULL,0,0,600, 400, SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOMOVE); SendMessage(hwnd,WM_USER+100,1,0); // refresh list } break; case WM_USER+100: switch (wParam) { case 0x103: // update directory combo box -- destroys buffer pointed to by lParam if (lParam) { char *path = (char*)lParam; HWND combo=GetDlgItem(hwnd,0x103); SendMessage(combo,CB_RESETCONTENT,0,0); WDL_remove_trailing_dirchars(path); while (path[0]) { SendMessage(combo,CB_ADDSTRING,0,(LPARAM)path); WDL_remove_filepart(path); WDL_remove_trailing_dirchars(path); } SendMessage(combo,CB_ADDSTRING,0,(LPARAM)"/"); SendMessage(combo,CB_SETCURSEL,0,0); } break; case 1: { BrowseFile_State *parms = (BrowseFile_State *)GetWindowLongPtr(hwnd,GWLP_USERDATA); if (parms) { char buf[maxPathLen]; const char *filt = NULL; buf[0]=0; int a = (int) SendDlgItemMessage(hwnd,0x105,CB_GETCURSEL,0,0); if (a>=0) filt = (const char *)SendDlgItemMessage(hwnd,0x105,CB_GETITEMDATA,a,0); a = (int) SendDlgItemMessage(hwnd,0x103,CB_GETCURSEL,0,0); if (a>=0) SendDlgItemMessage(hwnd,0x103,CB_GETLBTEXT,a,(LPARAM)buf); if (buf[0]) parms->scan_path(buf, filt, parms->mode == BrowseFile_State::OPENDIR); else parms->viewlist.DeleteAll(); HWND list = GetDlgItem(hwnd,0x104); ListView_SetItemCount(list, 0); // clear selection ListView_SetItemCount(list, parms->viewlist.GetSize()); ListView_RedrawItems(list,0, parms->viewlist.GetSize()); } } break; } break; case WM_GETMINMAXINFO: { LPMINMAXINFO p=(LPMINMAXINFO)lParam; p->ptMinTrackSize.x = 300; p->ptMinTrackSize.y = 300; } break; case WM_SIZE: { BrowseFile_State *parms = (BrowseFile_State *)GetWindowLongPtr(hwnd,GWLP_USERDATA); // reposition controls RECT r; GetClientRect(hwnd,&r); const int buth = 24, cancelbutw = 50, okbutw = parms->mode == BrowseFile_State::OPENDIR ? 120 : 50; const int xborder = 4, yborder=8; const int fnh = 20, fnlblw = parms->mode == BrowseFile_State::OPENDIR ? 70 : 50; int ypos = r.bottom - 4 - buth; int xpos = r.right; SetWindowPos(GetDlgItem(hwnd,IDCANCEL), NULL, xpos -= cancelbutw + xborder, ypos, cancelbutw,buth, SWP_NOZORDER|SWP_NOACTIVATE); SetWindowPos(GetDlgItem(hwnd,IDOK), NULL, xpos -= okbutw + xborder, ypos, okbutw,buth, SWP_NOZORDER|SWP_NOACTIVATE); HWND emb = GetDlgItem(hwnd,0x102); if (emb) { RECT sr; GetClientRect(emb,&sr); if (ypos > r.bottom-4-sr.bottom) ypos = r.bottom-4-sr.bottom; SetWindowPos(emb,NULL, xborder,ypos, xpos - xborder*2, sr.bottom, SWP_NOZORDER|SWP_NOACTIVATE); ShowWindow(emb,SW_SHOWNA); } HWND filt = GetDlgItem(hwnd,0x105); if (filt) { SetWindowPos(filt, NULL, xborder*2 + fnlblw, ypos -= fnh + yborder, r.right-fnlblw-xborder*3, fnh, SWP_NOZORDER|SWP_NOACTIVATE); } SetWindowPos(GetDlgItem(hwnd,0x100), NULL, xborder*2 + fnlblw, ypos -= fnh + yborder, r.right-fnlblw-xborder*3, fnh, SWP_NOZORDER|SWP_NOACTIVATE); SetWindowPos(GetDlgItem(hwnd,0x101), NULL, xborder, ypos, fnlblw, fnh, SWP_NOZORDER|SWP_NOACTIVATE); SetWindowPos(GetDlgItem(hwnd,0x103), NULL, xborder, 0, r.right-xborder*2, fnh, SWP_NOZORDER|SWP_NOACTIVATE); SetWindowPos(GetDlgItem(hwnd,0x104), NULL, xborder, fnh+yborder, r.right-xborder*2, ypos - (fnh+yborder) - yborder, SWP_NOZORDER|SWP_NOACTIVATE); } break; case WM_COMMAND: switch (LOWORD(wParam)) { case 0x105: if (HIWORD(wParam) == CBN_SELCHANGE) { SendMessage(hwnd,WM_USER+100,1,0); // refresh list } return 0; case 0x103: if (HIWORD(wParam) == CBN_SELCHANGE) { SendMessage(hwnd,WM_USER+100,1,0); // refresh list } return 0; case IDCANCEL: EndDialog(hwnd,0); return 0; case IDOK: { char buf[maxPathLen], msg[2048]; buf[0]=0; int a = (int) SendDlgItemMessage(hwnd,0x103,CB_GETCURSEL,0,0); if (a>=0) { SendDlgItemMessage(hwnd,0x103,CB_GETLBTEXT,a,(LPARAM)buf); size_t buflen = strlen(buf); if (!buflen) strcpy(buf,"/"); else { if (buflen > sizeof(buf)-2) buflen = sizeof(buf)-2; if (buf[buflen-1]!='/') { buf[buflen++] = '/'; buf[buflen]=0; } } } GetDlgItemText(hwnd,0x100,msg,sizeof(msg)); BrowseFile_State *parms = (BrowseFile_State *)GetWindowLongPtr(hwnd,GWLP_USERDATA); int cnt; if (parms->mode == BrowseFile_State::OPENMULTI && (cnt=ListView_GetSelectedCount(GetDlgItem(hwnd,0x104)))>1 && (!*msg || !strcmp(msg,multiple_files))) { HWND list = GetDlgItem(hwnd,0x104); WDL_TypedBuf<char> fs; fs.Set(buf,strlen(buf)+1); int a = ListView_GetNextItem(list,-1,LVNI_SELECTED); while (a != -1 && fs.GetSize() < 4096*4096 && cnt--) { const char *fn = NULL; struct BrowseFile_State::rec *rec = parms->viewlist.EnumeratePtr(a,&fn); if (!rec) break; if (*fn) fn++; // skip type ident fs.Add(fn,strlen(fn)+1); a = ListView_GetNextItem(list,a,LVNI_SELECTED); } fs.Add("",1); parms->fnout = (char*)malloc(fs.GetSize()); if (parms->fnout) memcpy(parms->fnout,fs.Get(),fs.GetSize()); EndDialog(hwnd,1); return 0; } else { if (msg[0] == '.' && (msg[1] == '.' || msg[1] == 0)) { if (msg[1] == '.') SendDlgItemMessage(hwnd,0x103,CB_SETCURSEL,a+1,0); SetDlgItemText(hwnd,0x100,""); SendMessage(hwnd,WM_USER+100,1,0); // refresh list return 0; } else if (msg[0] == '/') lstrcpyn_safe(buf,msg,sizeof(buf)); else lstrcatn(buf,msg,sizeof(buf)); } switch (parms->mode) { case BrowseFile_State::OPENDIR: if (!buf[0]) return 0; else if (msg[0]) { // navigate to directory if filepart set DIR *dir = opendir(buf); if (!dir) { snprintf(msg,sizeof(msg),"Error opening directory:\r\n\r\n%s\r\n\r\nCreate?",buf); if (MessageBox(hwnd,msg,"Create directory?",MB_OKCANCEL)==IDCANCEL) return 0; CreateDirectory(buf,NULL); dir=opendir(buf); } if (!dir) { MessageBox(hwnd,"Error creating directory","Error",MB_OK); return 0; } closedir(dir); SendMessage(hwnd, WM_USER+100, 0x103, (LPARAM)buf); SetDlgItemText(hwnd,0x100,""); SendMessage(hwnd,WM_USER+100,1,0); // refresh list return 0; } else { DIR *dir = opendir(buf); if (!dir) return 0; closedir(dir); } break; case BrowseFile_State::SAVE: if (!buf[0]) return 0; else { struct stat st={0,}; DIR *dir = opendir(buf); if (dir) { closedir(dir); SendMessage(hwnd, WM_USER+100, 0x103, (LPARAM)buf); SetDlgItemText(hwnd,0x100,""); SendMessage(hwnd,WM_USER+100,1,0); // refresh list return 0; } if (!stat(buf,&st)) { snprintf(msg,sizeof(msg),"File exists:\r\n\r\n%s\r\n\r\nOverwrite?",buf); if (MessageBox(hwnd,msg,"Overwrite file?",MB_OKCANCEL)==IDCANCEL) return 0; } } break; default: if (!buf[0]) return 0; else { struct stat st={0,}; DIR *dir = opendir(buf); if (dir) { closedir(dir); SendMessage(hwnd, WM_USER+100, 0x103, (LPARAM)buf); SetDlgItemText(hwnd,0x100,""); SendMessage(hwnd,WM_USER+100,1,0); // refresh list return 0; } if (stat(buf,&st)) { snprintf(msg,sizeof(msg),"File does not exist:\r\n\r\n%s",buf); MessageBox(hwnd,msg,"File not found",MB_OK); return 0; } } break; } if (parms->fnout) { lstrcpyn_safe(parms->fnout,buf,parms->fnout_sz); } else { size_t l = strlen(buf); parms->fnout = (char*)calloc(l+2,1); memcpy(parms->fnout,buf,l); } } EndDialog(hwnd,1); return 0; } break; case WM_NOTIFY: { LPNMHDR l=(LPNMHDR)lParam; if (l->code == LVN_GETDISPINFO) { BrowseFile_State *parms = (BrowseFile_State *)GetWindowLongPtr(hwnd,GWLP_USERDATA); NMLVDISPINFO *lpdi = (NMLVDISPINFO*) lParam; const int idx=lpdi->item.iItem; if (l->idFrom == 0x104 && parms && idx >=0 && idx < parms->viewlist.GetSize()) { const char *fn = NULL; struct BrowseFile_State::rec *rec = parms->viewlist.EnumeratePtr(idx,&fn); if (rec && fn) { if (lpdi->item.mask&LVIF_TEXT) { switch (lpdi->item.iSubItem) { case 0: if (fn[0]) lstrcpyn_safe(lpdi->item.pszText,fn+1,lpdi->item.cchTextMax); break; case 1: if (fn[0] == 1) { lstrcpyn_safe(lpdi->item.pszText,"<DIR>",lpdi->item.cchTextMax); } else { static const char *tab[]={ "bytes","KB","MB","GB" }; int lf=0; WDL_INT64 s=rec->size; if (s<1024) { snprintf(lpdi->item.pszText,lpdi->item.cchTextMax,"%d %s ",(int)s,tab[0]); break; } int w = 1; do { w++; lf = (int)(s&1023); s/=1024; } while (s >= 1024 && w<4); snprintf(lpdi->item.pszText,lpdi->item.cchTextMax,"%d.%d %s ",(int)s,(int)((lf*10.0)/1024.0+0.5),tab[w-1]); } break; case 2: if (rec->date > 0 && rec->date < WDL_INT64_CONST(0x793406fff)) { struct tm *a=localtime(&rec->date); if (a) { char str[512]; strftime(str,sizeof(str),"%c",a); lstrcpyn(lpdi->item.pszText, str,lpdi->item.cchTextMax); } } break; } } } } } else if (l->code == LVN_ODFINDITEM) { } else if (l->code == LVN_ITEMCHANGED) { const int selidx = ListView_GetNextItem(l->hwndFrom, -1, LVNI_SELECTED); if (selidx>=0) { BrowseFile_State *parms = (BrowseFile_State *)GetWindowLongPtr(hwnd,GWLP_USERDATA); if (parms && parms->mode == BrowseFile_State::OPENMULTI && ListView_GetSelectedCount(l->hwndFrom)>1) { SetDlgItemText(hwnd,0x100,multiple_files); } else { const char *fn = NULL; struct BrowseFile_State::rec *rec = parms ? parms->viewlist.EnumeratePtr(selidx,&fn) : NULL; if (rec) { if (fn && fn[0]) SetDlgItemText(hwnd,0x100,fn+1); } } } } else if (l->code == NM_DBLCLK) { SendMessage(hwnd,WM_COMMAND,IDOK,0); } } break; } return 0; }
void MultiTab_Editor::draw_top_line() { int ypos=0; if (m_top_margin > 1) { int xpos=0; int x; move(ypos++,0); const int cnt= GetTabCount(); int tsz=16; // this is duplicated in onMouseMessage if (cnt>0) tsz=COLS/cnt; if (tsz>128)tsz=128; if (tsz<12) tsz=12; for (x= 0; x < cnt && xpos < COLS; x ++) { MultiTab_Editor *ed = GetTab(x); if (ed) { char buf[128 + 8]; memset(buf,' ',tsz); const char *p = WDL_get_filepart(ed->GetFileName()); const int lp=strlen(p); int skip=0; if (x<9) { if (tsz>16) { #ifdef __APPLE__ memcpy(buf,"<Cmd+",skip=5); #else memcpy(buf,"<Ctrl+",skip=6); #endif } buf[skip++]='F'; buf[skip++] = '1'+x; buf[skip++] = '>'; skip++; } memcpy(buf+skip,p,min(tsz-1-skip,lp)); buf[tsz]=0; int l = tsz; if (l > COLS-xpos) l = COLS-xpos; if (ed == this) { attrset(SYNTAX_HIGHLIGHT2|A_BOLD); } else { attrset(A_NORMAL); } addnstr(buf,l); xpos += l; } } if (xpos < COLS) clrtoeol(); } attrset(COLOR_TOPLINE|A_BOLD); bkgdset(COLOR_TOPLINE); const char *p=GetFileName(); move(ypos,0); if (COLS>4) { const int pl = (int) strlen(p); if (pl > COLS-1 && COLS > 4) { addstr("..."); p+=pl - (COLS-1) + 4; } addstr(p); } clrtoeol(); }
HFONT CreateFont(int lfHeight, int lfWidth, int lfEscapement, int lfOrientation, int lfWeight, char lfItalic, char lfUnderline, char lfStrikeOut, char lfCharSet, char lfOutPrecision, char lfClipPrecision, char lfQuality, char lfPitchAndFamily, const char *lfFaceName) { HGDIOBJ__ *font=NULL; #ifdef SWELL_FREETYPE FT_Face face=NULL; if (!s_freetype_failed && !s_freetype) s_freetype_failed = !!FT_Init_FreeType(&s_freetype); if (s_freetype) { if (!lfFaceName || !*lfFaceName) lfFaceName = "Arial"; int fn_len = strlen(lfFaceName); const char *leadpath = "/usr/share/fonts/truetype/msttcorefonts"; // todo: scan subdirs? char tmp[1024]; char bestmatch[512]; bestmatch[0]=0; int x; for (x=0;x < s_registered_fonts.GetSize(); x ++) { const char *fn = s_registered_fonts.Get(x); if (fn) { const char *fnpart = WDL_get_filepart(fn); if (!strnicmp(fnpart,lfFaceName,strlen(lfFaceName))) { FT_New_Face(s_freetype,fn,0,&face); if (face) break; } } } if (!face) { snprintf(tmp,sizeof(tmp),"%s/%s.ttf",leadpath,lfFaceName); FT_New_Face(s_freetype,tmp,0,&face); } if (!face) { WDL_DirScan ds; if (!ds.First(leadpath)) do { if (!strnicmp(ds.GetCurrentFN(),lfFaceName,fn_len)) { if (!stricmp(ds.GetCurrentFN()+fn_len,".ttf")) { snprintf(tmp,sizeof(tmp),"%s/%s",leadpath,ds.GetCurrentFN()); FT_New_Face(s_freetype,tmp,0,&face); } else { // todo look for italic/bold/etc too int sl = strlen(ds.GetCurrentFN()); if (sl > 4 && !stricmp(ds.GetCurrentFN() + sl - 4, ".ttf") && (!bestmatch[0] || sl < strlen(bestmatch))) { lstrcpyn_safe(bestmatch,ds.GetCurrentFN(),sizeof(bestmatch)); } } } } while (!face && !ds.Next()); if (!face && bestmatch[0]) { snprintf(tmp,sizeof(tmp),"%s/%s",leadpath,bestmatch); FT_New_Face(s_freetype,tmp,0,&face); } } if (!face) FT_New_Face(s_freetype,"/usr/share/fonts/truetype/freefont/FreeSans.ttf",0,&face); if (!face) FT_New_Face(s_freetype,"/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf",0,&face); } if (face) { font = GDP_OBJECT_NEW(); font->type=TYPE_FONT; font->fontface = face; font->alpha = 1.0f; ////unsure here if (lfWidth<0) lfWidth=-lfWidth; if (lfHeight<0) lfHeight=-lfHeight; FT_Set_Char_Size(face,lfWidth*64, lfHeight*64,0,0); // 72dpi // FT_Set_Pixel_Sizes(face,0,lfHeight); } #else font->type=TYPE_FONT; #endif return font; }