static LRESULT CALLBACK RulerWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { if (uMsg == WM_SETCURSOR && g_actionInProgress && g_actionInProgress->SetMouseCursor) { if (HCURSOR cursor = g_actionInProgress->SetMouseCursor(BR_ContinuousAction::RULER)) { SetCursor(cursor); return 1; } } else if (uMsg == WM_MOUSEMOVE && g_actionInProgress && g_actionInProgress->SetTooltip) { WDL_FastString tooltip = g_actionInProgress->SetTooltip(BR_ContinuousAction::RULER); if (tooltip.GetLength()) { POINT p = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)}; ClientToScreen(hwnd, &p); SetTooltip(tooltip.Get(), &p); } else { SetTooltip(NULL, NULL); } } return g_rulerWndProc(hwnd, uMsg, wParam, lParam); }
// Functions for getting/setting track FX chains void GetFXChain(MediaTrack* tr, WDL_TypedBuf<char>* buf) { SNM_ChunkParserPatcher p(tr); WDL_FastString chainChunk; if (p.GetSubChunk("FXCHAIN", 2, 0, &chainChunk, "<ITEM") > 0) { buf->Resize(chainChunk.GetLength() + 1); strcpy(buf->Get(), chainChunk.Get()); } }
void SetFXChain(MediaTrack* tr, const char* str) { SNM_FXChainTrackPatcher p(tr); WDL_FastString chainChunk; // adapt FX chain format (the SNM_FXChainTrackPatcher uses the .RFXChain file format) if (str && !strncmp(str, "<FXCHAIN", 8)) { chainChunk.Set(strchr(str, '\n') + 1); // removes the line starting with "<FXCHAIN" chainChunk.SetLen(chainChunk.GetLength()-2); // remove trailing ">\n" } p.SetFXChain(str ? &chainChunk : NULL); }
// split the text into lines and store them (not to do that in OnPaint()), // empty lines are ignored // _col: 0 to use the default theme text color void SNM_DynSizedText::SetText(const char* _txt, int _col, unsigned char _alpha) { if (m_col==_col && m_alpha==_alpha && !strcmp(m_lastText.Get(), _txt?_txt:"")) return; m_lastText.Set(_txt?_txt:""); m_lines.Empty(true); m_maxLineIdx = -1; m_alpha = _alpha; m_col = _col ? LICE_RGBA_FROMNATIVE(_col, m_alpha) : 0; if (_txt && *_txt) { int maxLineLen=0, len; const char* p=_txt, *p2=NULL; while (p2 = FindFirstRN(p, true)) // \r or \n in any order (for OSX..) { if (len = (int)(p2-p)) { if (len > maxLineLen) { maxLineLen = len; m_maxLineIdx = m_lines.GetSize(); } WDL_FastString* line = new WDL_FastString; line->Append(p, len); m_lines.Add(line); p = p2+1; } while (*p && (*p == '\r' || *p == '\n')) p++; if (!*p) break; } if (p && *p && !p2) { WDL_FastString* s = new WDL_FastString(p); if (s->GetLength() > maxLineLen) m_maxLineIdx = m_lines.GetSize(); m_lines.Add(s); } } m_lastFontH = -1; // will force font refresh RequestRedraw(NULL); }
void WDL_CursesEditor::runSearch() { if (s_search_string[0]) { int wrapflag=0,found=0; int line; int numlines = m_text.GetSize(); int startx=m_curs_x+1; const int srchlen=strlen(s_search_string); for (line = m_curs_y; line < numlines && !found; line ++) { WDL_FastString *tl = m_text.Get(line); const char *p; if (tl && (p=tl->Get())) { const int linelen = tl->GetLength(); for (; startx <= linelen-srchlen; startx++) if (!strnicmp(p+startx,s_search_string,srchlen)) { m_select_y1=m_select_y2=m_curs_y=line; m_select_x1=m_curs_x=startx; m_select_x2=startx+srchlen; m_selecting=1; found=1; break; } } startx=0; } if (!found && (m_curs_y>0 || m_curs_x > 0)) { wrapflag=1; numlines = min(m_curs_y+1,numlines); for (line = 0; line < numlines && !found; line ++) { WDL_FastString *tl = m_text.Get(line); const char *p; if (tl && (p=tl->Get())) { const int linelen = tl->GetLength(); for (; startx <= linelen-srchlen; startx++) if (!strnicmp(p+startx,s_search_string,srchlen)) { m_select_y1=m_select_y2=m_curs_y=line; m_select_x1=m_curs_x=startx; m_select_x2=startx+srchlen; m_selecting=1; found=1; break; } } startx=0; } } if (found) { draw(); setCursor(); char buf[512]; snprintf(buf,sizeof(buf),"Found %s'%s' Ctrl+G:next",wrapflag?"(wrapped) ":"",s_search_string); draw_message(buf); return; } } draw(); setCursor(); char buf[512]; if (s_search_string[0]) snprintf(buf,sizeof(buf),"String '%s' not found",s_search_string); else lstrcpyn_safe(buf,"No search string",sizeof(buf)); draw_message(buf); }
int WDL_CursesEditor::onChar(int c) { if (m_state == -3 || m_state == -4) { switch (c) { case '\r': case '\n': m_state=0; runSearch(); break; case 27: m_state=0; draw(); setCursor(); draw_message("Find cancelled."); break; case KEY_BACKSPACE: if (s_search_string[0]) s_search_string[strlen(s_search_string)-1]=0; m_state=-4; break; default: if (VALIDATE_TEXT_CHAR(c)) { int l=m_state == -3 ? 0 : strlen(s_search_string); m_state = -4; if (l < (int)sizeof(s_search_string)-1) { s_search_string[l]=c; s_search_string[l+1]=0; } } break; } if (m_state) { attrset(m_color_message); bkgdset(m_color_message); mvaddstr(LINES-1,29,s_search_string); clrtoeol(); attrset(0); bkgdset(0); } return 0; } if (c==KEY_DOWN || c==KEY_UP || c==KEY_PPAGE||c==KEY_NPAGE || c==KEY_RIGHT||c==KEY_LEFT||c==KEY_HOME||c==KEY_END) { if (SHIFT_KEY_DOWN) { if (!m_selecting) { m_select_x2=m_select_x1=m_curs_x; m_select_y2=m_select_y1=m_curs_y; m_selecting=1; } } else if (m_selecting) { m_selecting=0; draw(); } } switch(c) { case 'O'-'A'+1: if (!SHIFT_KEY_DOWN && !ALT_KEY_DOWN) { if (m_pane_div <= 0.0 || m_pane_div >= 1.0) { onChar('P'-'A'+1); } if (m_pane_div > 0.0 && m_pane_div < 1.0) { m_curpane=!m_curpane; draw(); draw_status_state(); int paney[2], paneh[2]; GetPaneDims(paney, paneh); if (m_curs_y-m_paneoffs_y[m_curpane] < 0) m_curs_y=m_paneoffs_y[m_curpane]; else if (m_curs_y-m_paneoffs_y[m_curpane] >= paneh[m_curpane]) m_curs_y=paneh[m_curpane]+m_paneoffs_y[m_curpane]-1; setCursor(); } } break; case 'P'-'A'+1: if (!SHIFT_KEY_DOWN && !ALT_KEY_DOWN) { if (m_pane_div <= 0.0 || m_pane_div >= 1.0) { m_pane_div=0.5; m_paneoffs_y[1]=m_paneoffs_y[0]; } else { m_pane_div=1.0; if (m_curpane) m_paneoffs_y[0]=m_paneoffs_y[1]; m_curpane=0; } draw(); draw_status_state(); int paney[2], paneh[2]; const int pane_divy=GetPaneDims(paney, paneh); setCursor(); } break; case 407: case 'Z'-'A'+1: if (!SHIFT_KEY_DOWN && !ALT_KEY_DOWN) { if (m_undoStack_pos > 0) { m_undoStack_pos--; loadUndoState(m_undoStack.Get(m_undoStack_pos)); draw(); setCursor(); char buf[512]; snprintf(buf,sizeof(buf),"Undid action - %d items in undo buffer",m_undoStack_pos); draw_message(buf); } else { draw_message("Can't Undo"); } break; } // fall through case 'Y'-'A'+1: if ((c == 'Z'-'A'+1 || !SHIFT_KEY_DOWN) && !ALT_KEY_DOWN) { if (m_undoStack_pos < m_undoStack.GetSize()-1) { m_undoStack_pos++; loadUndoState(m_undoStack.Get(m_undoStack_pos)); draw(); setCursor(); char buf[512]; snprintf(buf,sizeof(buf),"Redid action - %d items in redo buffer",m_undoStack.GetSize()-m_undoStack_pos-1); draw_message(buf); } else { draw_message("Can't Redo"); } } break; case KEY_IC: if (!SHIFT_KEY_DOWN && !ALT_KEY_DOWN) { s_overwrite=!s_overwrite; setCursor(); break; } // fqll through case 'V'-'A'+1: if (!SHIFT_KEY_DOWN && !ALT_KEY_DOWN) { // generate a m_clipboard using win32 clipboard data WDL_PtrList<const char> lines; WDL_String buf; #ifdef WDL_IS_FAKE_CURSES if (CURSES_INSTANCE) { OpenClipboard(CURSES_INSTANCE->m_hwnd); HANDLE h=GetClipboardData(CF_TEXT); if (h) { char *t=(char *)GlobalLock(h); int s=GlobalSize(h); buf.Set(t,s); GlobalUnlock(t); } CloseClipboard(); } else #endif { buf.Set(s_fake_clipboard.Get()); } if (buf.Get() && buf.Get()[0]) { char *src=buf.Get(); while (*src) { char *seek=src; while (*seek && *seek != '\r' && *seek != '\n') seek++; char hadclr=*seek; if (*seek) *seek++=0; lines.Add(src); if (hadclr == '\r' && *seek == '\n') seek++; if (hadclr && !*seek) { lines.Add(""); } src=seek; } } if (lines.GetSize()) { removeSelect(); // insert lines at m_curs_y,m_curs_x if (m_curs_y >= m_text.GetSize()) m_curs_y=m_text.GetSize()-1; if (m_curs_y < 0) m_curs_y=0; preSaveUndoState(); WDL_FastString poststr; int x; int indent_to_pos = -1; for (x = 0; x < lines.GetSize(); x ++) { WDL_FastString *str=m_text.Get(m_curs_y); const char *tstr=lines.Get(x); if (!tstr) tstr=""; if (!x) { if (str) { if (m_curs_x < 0) m_curs_x=0; int tmp=str->GetLength(); if (m_curs_x > tmp) m_curs_x=tmp; poststr.Set(str->Get()+m_curs_x); str->SetLen(m_curs_x); const char *p = str->Get(); while (*p == ' ' || *p == '\t') p++; if (!*p && p > str->Get()) { if (lines.GetSize()>1) { while (*tstr == ' ' || *tstr == '\t') tstr++; } indent_to_pos = m_curs_x; } str->Append(tstr); } else { m_text.Insert(m_curs_y,(str=new WDL_FastString(tstr))); } if (lines.GetSize() > 1) { m_curs_y++; } else { m_curs_x = str->GetLength(); str->Append(poststr.Get()); } } else if (x == lines.GetSize()-1) { WDL_FastString *s=newIndentedFastString(tstr,indent_to_pos); m_curs_x = s->GetLength(); s->Append(poststr.Get()); m_text.Insert(m_curs_y,s); } else { m_text.Insert(m_curs_y,newIndentedFastString(tstr,indent_to_pos)); m_curs_y++; } } draw(); setCursor(); draw_message("Pasted"); saveUndoState(); } else { setCursor(); draw_message("Clipboard empty"); } } break; case KEY_DC: if (!SHIFT_KEY_DOWN && !ALT_KEY_DOWN) { WDL_FastString *s; if (m_selecting) { preSaveUndoState(); removeSelect(); draw(); saveUndoState(); setCursor(); } else if ((s=m_text.Get(m_curs_y))) { if (m_curs_x < s->GetLength()) { preSaveUndoState(); bool hadCom = LineCanAffectOtherLines(s->Get(),m_curs_x,1); s->DeleteSub(m_curs_x,1); if (!hadCom) hadCom = LineCanAffectOtherLines(s->Get(),-1,-1); draw(hadCom ? -1 : m_curs_y); saveUndoState(); setCursor(); } else // append next line to us { if (m_curs_y < m_text.GetSize()-1) { preSaveUndoState(); WDL_FastString *nl=m_text.Get(m_curs_y+1); if (nl) { s->Append(nl->Get()); } m_text.Delete(m_curs_y+1,true); draw(); saveUndoState(); setCursor(); } } } break; } case 'C'-'A'+1: case 'X'-'A'+1: if (!SHIFT_KEY_DOWN && !ALT_KEY_DOWN && m_selecting) { if (c!= 'C'-'A'+1) m_selecting=0; int miny,maxy,minx,maxx; int x; getselectregion(minx,miny,maxx,maxy); const char *status=""; char statusbuf[512]; if (minx != maxx|| miny != maxy) { int bytescopied=0; s_fake_clipboard.Set(""); int lht=0,fht=0; if (c != 'C'-'A'+1) preSaveUndoState(); for (x = miny; x <= maxy; x ++) { WDL_FastString *s=m_text.Get(x); if (s) { const char *str=s->Get(); int sx,ex; if (x == miny) sx=max(minx,0); else sx=0; int tmp=s->GetLength(); if (sx > tmp) sx=tmp; if (x == maxy) ex=min(maxx,tmp); else ex=tmp; bytescopied += ex-sx + (x!=maxy); if (s_fake_clipboard.Get() && s_fake_clipboard.Get()[0]) s_fake_clipboard.Append("\r\n"); s_fake_clipboard.Append(ex-sx?str+sx:"",ex-sx); if (c != 'C'-'A'+1) { if (sx == 0 && ex == tmp) // remove entire line { m_text.Delete(x,true); if (x==miny) miny--; x--; maxy--; } else { if (x==miny) fht=1; if (x == maxy) lht=1; s->DeleteSub(sx,ex-sx); } } } } if (fht && lht && miny+1 == maxy) { m_text.Get(miny)->Append(m_text.Get(maxy)->Get()); m_text.Delete(maxy,true); } if (c != 'C'-'A'+1) { m_curs_y=miny; if (m_curs_y < 0) m_curs_y=0; m_curs_x=minx; saveUndoState(); snprintf(statusbuf,sizeof(statusbuf),"Cut %d bytes",bytescopied); } else snprintf(statusbuf,sizeof(statusbuf),"Copied %d bytes",bytescopied); #ifdef WDL_IS_FAKE_CURSES if (CURSES_INSTANCE) { int l=s_fake_clipboard.GetLength()+1; HANDLE h=GlobalAlloc(GMEM_MOVEABLE,l); void *t=GlobalLock(h); memcpy(t,s_fake_clipboard.Get(),l); GlobalUnlock(h); OpenClipboard(CURSES_INSTANCE->m_hwnd); EmptyClipboard(); SetClipboardData(CF_TEXT,h); CloseClipboard(); } #endif status=statusbuf; } else status="No selection"; draw(); setCursor(); draw_message(status); } break; case 'A'-'A'+1: if (!SHIFT_KEY_DOWN && !ALT_KEY_DOWN) { m_selecting=1; m_select_x1=0; m_select_y1=0; m_select_y2=m_text.GetSize()-1; m_select_x2=0; if (m_text.Get(m_select_y2)) m_select_x2=m_text.Get(m_select_y2)->GetLength(); draw(); setCursor(); } break; case 27: if (!SHIFT_KEY_DOWN && !ALT_KEY_DOWN && m_selecting) { m_selecting=0; draw(); setCursor(); break; } break; case KEY_F3: case 'G'-'A'+1: if (!SHIFT_KEY_DOWN && !ALT_KEY_DOWN && s_search_string[0]) { runSearch(); return 0; } // fall through case 'F'-'A'+1: if (!SHIFT_KEY_DOWN && !ALT_KEY_DOWN) { draw_message(""); attrset(m_color_message); bkgdset(m_color_message); mvaddstr(LINES-1,0,"Find string (ESC to cancel): "); if (m_selecting && m_select_y1==m_select_y2) { WDL_FastString* s=m_text.Get(m_select_y1); if (s) { const char* p=s->Get(); int xlo=min(m_select_x1, m_select_x2); int xhi=max(m_select_x1, m_select_x2); int i; for (i=xlo; i < xhi; ++i) { if (!isalnum(p[i]) && p[i] != '_') break; } if (i == xhi && xhi > xlo && xhi-xlo < sizeof(s_search_string)) { lstrcpyn(s_search_string, p+xlo, xhi-xlo+1); } } } addstr(s_search_string); clrtoeol(); attrset(0); bkgdset(0); m_state=-3; // find, initial (m_state=4 when we've typed something) } break; case KEY_DOWN: { if (CTRL_KEY_DOWN) { int paney[2], paneh[2]; GetPaneDims(paney, paneh); int maxscroll=m_text.GetSize()-paneh[m_curpane]+4; if (m_paneoffs_y[m_curpane] < maxscroll-1) { m_paneoffs_y[m_curpane]++; if (m_curs_y < m_paneoffs_y[m_curpane]) m_curs_y=m_paneoffs_y[m_curpane]; draw(); } } else { m_curs_y++; if (m_curs_y>=m_text.GetSize()) m_curs_y=m_text.GetSize()-1; if (m_curs_y < 0) m_curs_y=0; } if (m_selecting) { setCursor(1); m_select_x2=m_curs_x; m_select_y2=m_curs_y; draw(); } setCursor(1); } break; case KEY_UP: { if (CTRL_KEY_DOWN) { if (m_paneoffs_y[m_curpane] > 0) { int paney[2], paneh[2]; GetPaneDims(paney, paneh); m_paneoffs_y[m_curpane]--; if (m_curs_y > m_paneoffs_y[m_curpane]+paneh[m_curpane]-1) m_curs_y = m_paneoffs_y[m_curpane]+paneh[m_curpane]-1; if (m_curs_y < 0) m_curs_y=0; draw(); } } else { if(m_curs_y>0) m_curs_y--; } if (m_selecting) { setCursor(1); m_select_x2=m_curs_x; m_select_y2=m_curs_y; draw(); } setCursor(1); } break; case KEY_PPAGE: { if (m_curs_y > m_paneoffs_y[m_curpane]) { m_curs_y=m_paneoffs_y[m_curpane]; if (m_curs_y < 0) m_curs_y=0; } else { int paney[2], paneh[2]; GetPaneDims(paney, paneh); m_curs_y -= paneh[m_curpane]; if (m_curs_y < 0) m_curs_y=0; m_paneoffs_y[m_curpane]=m_curs_y; } if (m_selecting) { setCursor(1); m_select_x2=m_curs_x; m_select_y2=m_curs_y; } draw(); setCursor(1); } break; case KEY_NPAGE: { int paney[2], paneh[2]; GetPaneDims(paney, paneh); if (m_curs_y >= m_paneoffs_y[m_curpane]+paneh[m_curpane]-1) m_paneoffs_y[m_curpane]=m_curs_y-1; m_curs_y = m_paneoffs_y[m_curpane]+paneh[m_curpane]-1; if (m_curs_y >= m_text.GetSize()) m_curs_y=m_text.GetSize()-1; if (m_curs_y < 0) m_curs_y=0; if (m_selecting) { setCursor(1); m_select_x2=m_curs_x; m_select_y2=m_curs_y; } draw(); setCursor(1); } break; case KEY_RIGHT: { if (1) // wrap across lines { WDL_FastString *s = m_text.Get(m_curs_y); if (s && m_curs_x >= s->GetLength() && m_curs_y < m_text.GetSize()) { m_curs_y++; m_curs_x = -1; } } if(m_curs_x<0) { m_curs_x=0; } else { if (CTRL_KEY_DOWN) { WDL_FastString *s = m_text.Get(m_curs_y); if (!s||m_curs_x >= s->GetLength()) break; int lastType = categorizeCharForWordNess(s->Get()[m_curs_x++]); while (m_curs_x < s->GetLength()) { int thisType = categorizeCharForWordNess(s->Get()[m_curs_x]); if (thisType != lastType && thisType != 0) break; lastType=thisType; m_curs_x++; } } else { m_curs_x++; } } if (m_selecting) { setCursor(); m_select_x2=m_curs_x; m_select_y2=m_curs_y; draw(); } setCursor(); } break; case KEY_LEFT: { bool doMove=true; if (1) // wrap across lines { WDL_FastString *s = m_text.Get(m_curs_y); if (s && m_curs_y>0 && m_curs_x == 0) { s = m_text.Get(--m_curs_y); if (s) { m_curs_x = s->GetLength(); doMove=false; } } } if(m_curs_x>0 && doMove) { if (CTRL_KEY_DOWN) { WDL_FastString *s = m_text.Get(m_curs_y); if (!s) break; if (m_curs_x > s->GetLength()) m_curs_x = s->GetLength(); m_curs_x--; int lastType = categorizeCharForWordNess(s->Get()[m_curs_x--]); while (m_curs_x >= 0) { int thisType = categorizeCharForWordNess(s->Get()[m_curs_x]); if (thisType != lastType && lastType != 0) break; lastType=thisType; m_curs_x--; } m_curs_x++; } else { m_curs_x--; } } if (m_selecting) { setCursor(); m_select_x2=m_curs_x; m_select_y2=m_curs_y; draw(); } setCursor(); } break; case KEY_HOME: { m_curs_x=0; if (CTRL_KEY_DOWN) m_curs_y=0; if (m_selecting) { setCursor(); m_select_x2=m_curs_x; m_select_y2=m_curs_y; draw(); } setCursor(); } break; case KEY_END: { if (m_text.Get(m_curs_y)) m_curs_x=m_text.Get(m_curs_y)->GetLength(); if (CTRL_KEY_DOWN) m_curs_y=m_text.GetSize(); if (m_selecting) { setCursor(); m_select_x2=m_curs_x; m_select_y2=m_curs_y; draw(); } setCursor(); } break; case KEY_BACKSPACE: // backspace, baby if (m_selecting) { preSaveUndoState(); removeSelect(); draw(); saveUndoState(); setCursor(); } else if (m_curs_x > 0) { WDL_FastString *tl=m_text.Get(m_curs_y); if (tl) { preSaveUndoState(); bool hadCom = LineCanAffectOtherLines(tl->Get(), m_curs_x-1,1); tl->DeleteSub(--m_curs_x,1); if (!hadCom) hadCom = LineCanAffectOtherLines(tl->Get(),-1,-1); draw(hadCom?-1:m_curs_y); saveUndoState(); setCursor(); } } else // append current line to previous line { WDL_FastString *fl=m_text.Get(m_curs_y-1), *tl=m_text.Get(m_curs_y); if (!tl) { m_curs_y--; if (fl) m_curs_x=fl->GetLength(); draw(); saveUndoState(); setCursor(); } else if (fl) { preSaveUndoState(); m_curs_x=fl->GetLength(); fl->Append(tl->Get()); m_text.Delete(m_curs_y--,true); draw(); saveUndoState(); setCursor(); } } break; case 'L'-'A'+1: if (!SHIFT_KEY_DOWN && !ALT_KEY_DOWN) { draw(); setCursor(); } break; case 13: //KEY_ENTER: //insert newline preSaveUndoState(); if (m_selecting) { removeSelect(); draw(); setCursor(); } if (m_curs_y >= m_text.GetSize()) { m_curs_y=m_text.GetSize(); m_text.Add(new WDL_FastString); } if (s_overwrite) { WDL_FastString *s = m_text.Get(m_curs_y); int plen=0; const char *pb=NULL; if (s) { pb = s->Get(); while (plen < m_curs_x && (pb[plen]== ' ' || pb[plen] == '\t')) plen++; } if (++m_curs_y >= m_text.GetSize()) { m_curs_y = m_text.GetSize(); WDL_FastString *ns=new WDL_FastString; if (plen>0) ns->Set(pb,plen); m_text.Insert(m_curs_y,ns); } s = m_text.Get(m_curs_y); if (s && plen > s->GetLength()) plen=s->GetLength(); m_curs_x=plen; } else { WDL_FastString *s = m_text.Get(m_curs_y); if (s) { if (m_curs_x > s->GetLength()) m_curs_x = s->GetLength(); WDL_FastString *nl = new WDL_FastString(); int plen=0; const char *pb = s->Get(); while (plen < m_curs_x && (pb[plen]== ' ' || pb[plen] == '\t')) plen++; if (plen>0) nl->Set(pb,plen); nl->Append(pb+m_curs_x); m_text.Insert(++m_curs_y,nl); s->SetLen(m_curs_x); m_curs_x=plen; } } m_offs_x=0; draw(); saveUndoState(); setCursor(); break; case '\t': if (m_selecting) { preSaveUndoState(); bool isRev = !!(GetAsyncKeyState(VK_SHIFT)&0x8000); indentSelect(isRev?-m_indent_size:m_indent_size); // indent selection: draw(); setCursor(); saveUndoState(); break; } default: //insert char if(VALIDATE_TEXT_CHAR(c)) { preSaveUndoState(); if (m_selecting) { removeSelect(); draw(); setCursor(); } if (!m_text.Get(m_curs_y)) m_text.Insert(m_curs_y,new WDL_FastString); WDL_FastString *ss; if ((ss=m_text.Get(m_curs_y))) { char str[64]; int slen ; if (c == '\t') { slen = min(m_indent_size,64); if (slen<1) slen=1; int x; for(x=0;x<slen;x++) str[x]=' '; } else { str[0]=c; slen = 1; } bool hadCom = LineCanAffectOtherLines(ss->Get(),-1,-1); if (s_overwrite) { if (!hadCom) hadCom = LineCanAffectOtherLines(ss->Get(),m_curs_x,slen); ss->DeleteSub(m_curs_x,slen); } ss->Insert(str,m_curs_x,slen); if (!hadCom) hadCom = LineCanAffectOtherLines(ss->Get(),m_curs_x,slen); m_curs_x += slen; draw(hadCom ? -1 : m_curs_y); } saveUndoState(); setCursor(); } break; } return 0; }
static bool ContinuousActionInit (bool init, int cmd, BR_ContinuousAction* action) { static accelerator_register_t s_accelerator = { ContinuousActionTranslateAccel, TRUE, NULL }; bool initSuccessful = true; if (init) { GetConfig("tooltips", g_tooltips); g_actionInProgress = action; if (g_actionInProgress) { if (g_actionInProgress->Init) initSuccessful = g_actionInProgress->Init(true); } else initSuccessful = false; if (initSuccessful) { if (g_actionInProgress->SetMouseCursor || g_actionInProgress->SetTooltip) { SetConfig("tooltips", SetBit(SetBit(SetBit(g_tooltips, 0), 1), 2)); if (!g_arrangeWndProc && GetArrangeWnd()) { if (g_actionInProgress->SetTooltip) { WDL_FastString tooltip = g_actionInProgress->SetTooltip(BR_ContinuousAction::ARRANGE); if (tooltip.GetLength()) { POINT p; GetCursorPos(&p); SetTooltip(tooltip.Get(), &p); } } g_arrangeWndProc = (WNDPROC)SetWindowLongPtr(GetArrangeWnd(), GWLP_WNDPROC, (LONG_PTR)ArrangeWndProc); if (g_actionInProgress->SetMouseCursor && g_actionInProgress->SetMouseCursor(BR_ContinuousAction::ARRANGE)) SendMessage(GetArrangeWnd(), WM_SETCURSOR, (WPARAM)GetArrangeWnd(), 0); InvalidateRect(GetArrangeWnd(), NULL, TRUE); // kill existing native tooltip, if any } if (!g_rulerWndProc && GetRulerWndAlt()) { if (g_actionInProgress->SetTooltip) { WDL_FastString tooltip = g_actionInProgress->SetTooltip(BR_ContinuousAction::RULER); if (tooltip.GetLength()) { POINT p; GetCursorPos(&p); SetTooltip(tooltip.Get(), &p); } } g_rulerWndProc = (WNDPROC)SetWindowLongPtr(GetRulerWndAlt(), GWLP_WNDPROC, (LONG_PTR)RulerWndProc); if (g_actionInProgress->SetMouseCursor && g_actionInProgress->SetMouseCursor(BR_ContinuousAction::RULER)) SendMessage(GetRulerWndAlt(), WM_SETCURSOR, (WPARAM)GetRulerWndAlt(), 0); InvalidateRect(GetRulerWndAlt(), NULL, TRUE); } } plugin_register("accelerator", &s_accelerator); plugin_register("timer", (void*)ContinuousActionTimer); } else { g_actionInProgress = NULL; } } else { SetConfig("tooltips", g_tooltips); if (g_arrangeWndProc && GetArrangeWnd()) { SetWindowLongPtr(GetArrangeWnd(), GWLP_WNDPROC, (LONG_PTR)g_arrangeWndProc); SendMessage(GetArrangeWnd(), WM_SETCURSOR, (WPARAM)GetArrangeWnd(), 0); InvalidateRect(GetArrangeWnd(), NULL, FALSE); g_arrangeWndProc = NULL; } if (g_rulerWndProc && GetRulerWndAlt()) { SetWindowLongPtr(GetRulerWndAlt(), GWLP_WNDPROC, (LONG_PTR)g_rulerWndProc); SendMessage(GetRulerWndAlt(), WM_SETCURSOR, (WPARAM)GetRulerWndAlt(), 0); InvalidateRect(GetRulerWndAlt(), NULL, FALSE); g_rulerWndProc = NULL; } SetTooltip(NULL, NULL); plugin_register("-accelerator", &s_accelerator); plugin_register("-timer", (void*)ContinuousActionTimer); if (g_actionInProgress->Init) g_actionInProgress->Init(false); g_actionInProgress = NULL; } return initSuccessful; }
void MultiTab_Editor::OpenFileInTab(const char *fnp) { // try to find file to open WDL_FastString s; FILE *fp=NULL; { const char *ptr = fnp; while (!fp && *ptr) { // first try same path as loading effect if (m_filename.Get()[0]) { s.Set(m_filename.Get()); const char *sp=s.Get()+s.GetLength(); while (sp>=s.Get() && *sp != '\\' && *sp != '/') sp--; s.SetLen(sp + 1 - s.Get()); if (s.GetLength()) { s.Append(ptr); fp=fopenUTF8(s.Get(),"rb"); } } // scan past any / or \\, and try again if (!fp) { while (*ptr && *ptr != '\\' && *ptr != '/') ptr++; if (*ptr) ptr++; } } } if (!fp) { s.Set(""); fp = tryToFindOrCreateFile(fnp,&s); } if (!fp && s.Get()[0]) { m_newfn.Set(s.Get()); if (COLS > 25) { int allowed = COLS-25; if (s.GetLength()>allowed) { s.DeleteSub(0,s.GetLength() - allowed + 3); s.Insert("...",0); } s.Insert("Create new file '",0); s.Append("' (Y/n)? "); } else s.Set("Create new file (Y/n)? "); m_state=UI_STATE_SAVE_AS_NEW; attrset(m_color_message); bkgdset(m_color_message); mvaddstr(LINES-1,0,s.Get()); clrtoeol(); attrset(0); bkgdset(0); } else if (fp) { fclose(fp); int x; for (x=0;x<GetTabCount();x++) { MultiTab_Editor *e = GetTab(x); if (e && !stricmp(e->GetFileName(),s.Get())) { SwitchTab(x,false); return; } } AddTab(s.Get()); } }
bool BR_MidiEditor::Build () { m_take = (m_midiEditor) ? SWS_MIDIEditor_GetTake(m_midiEditor) : m_take; if (m_take) { MediaItem* item = GetMediaItemTake_Item(m_take); int takeId = GetTakeId(m_take, item); if (takeId >= 0) { SNM_TakeParserPatcher p(item, CountTakes(item)); WDL_FastString takeChunk; if (p.GetTakeChunk(takeId, &takeChunk)) { SNM_ChunkParserPatcher ptk(&takeChunk, false); LineParser lp(false); int laneId = 0; WDL_FastString lineLane; while (ptk.Parse(SNM_GET_SUBCHUNK_OR_LINE, 1, "SOURCE", "VELLANE", laneId++, -1, &lineLane)) { lp.parse(lineLane.Get()); m_ccLanes.push_back(lp.gettoken_int(1)); m_ccLanesHeight.push_back(lp.gettoken_int(((m_midiEditor) ? 2 : 3))); if (!m_midiEditor && m_ccLanesHeight.back() == 0) m_ccLanesHeight.back() = INLINE_MIDI_LANE_DIVIDER_H; // sometimes REAPER will return 0 when lane is completely hidden, but divider will still be visible lineLane.DeleteSub(0, lineLane.GetLength()); } WDL_FastString dataLine; if (ptk.Parse(SNM_GET_SUBCHUNK_OR_LINE, 1, "SOURCE", "HASDATA", 0, -1, &dataLine)) { lp.parse(dataLine.Get()); m_ppq = lp.gettoken_int(2); } else if (ptk.Parse(SNM_GET_SUBCHUNK_OR_LINE, 1, "SOURCE", "FILE", 0, -1, &dataLine)) { lp.parse(dataLine.Get()); m_ppq = GetMIDIFilePPQ (lp.gettoken_str(1)); if (!m_ppq) return false; } else return false; WDL_FastString lineView; if (ptk.Parse(SNM_GET_SUBCHUNK_OR_LINE, 1, "SOURCE", "CFGEDITVIEW", 0, -1, &lineView)) { lp.parse(lineView.Get()); m_startPos = (m_midiEditor) ? lp.gettoken_float(1) : GetMediaItemInfo_Value(GetMediaItemTake_Item(m_take), "D_POSITION"); m_hZoom = (m_midiEditor) ? lp.gettoken_float(2) : GetHZoomLevel(); m_vPos = (m_midiEditor) ? lp.gettoken_int(3) : lp.gettoken_int(7); m_vZoom = (m_midiEditor) ? lp.gettoken_int(4) : lp.gettoken_int(6); } else return false; WDL_FastString lineFilter; if (ptk.Parse(SNM_GET_SUBCHUNK_OR_LINE, 1, "SOURCE", "EVTFILTER", 0, -1, &lineFilter)) { lp.parse(lineFilter.Get()); m_filterEnabled = !!GetBit(lp.gettoken_int(7), 0); m_filterInverted = !!GetBit(lp.gettoken_int(7), 2); m_filterChannel = lp.gettoken_int(1); m_filterEventType = lp.gettoken_int(2); m_filterEventParam = !!lp.gettoken_int(16); m_filterEventVal = !!lp.gettoken_int(8); m_filterEventPos = !!lp.gettoken_int(14); m_filterEventLen = !!lp.gettoken_int(9); m_filterEventParamLo = lp.gettoken_int(17); m_filterEventParamHi = lp.gettoken_int(18); m_filterEventValLo = lp.gettoken_int(4); m_filterEventValHi = lp.gettoken_int(5); m_filterEventPosRepeat = lp.gettoken_float(15); m_filterEventPosLo = lp.gettoken_float(12); m_filterEventPosHi = lp.gettoken_float(13); m_filterEventLenLo = lp.gettoken_float(10); m_filterEventLenHi = lp.gettoken_float(11); } else return false; WDL_FastString lineProp; if (ptk.Parse(SNM_GET_SUBCHUNK_OR_LINE, 1, "SOURCE", "CFGEDIT", 0, -1, &lineProp)) { lp.parse(lineProp.Get()); m_pianoroll = (m_midiEditor) ? lp.gettoken_int(6) : 0; // inline midi editor doesn't have piano roll modes m_drawChannel = lp.gettoken_int(9) - 1; m_noteshow = lp.gettoken_int(18); m_timebase = (m_midiEditor) ? lp.gettoken_int(19) : PROJECT_SYNC; } else return false; // A few "corrections" for easier manipulation afterwards if (m_filterChannel == 0) m_filterChannel = ~m_filterChannel; if (m_filterEventParamLo < 0) m_filterEventParamLo = 0; if (m_filterEventParamHi < 0) m_filterEventParamHi = INT_MAX; if (m_filterEventValLo < 0) m_filterEventValLo = 0; if (m_filterEventValHi < 0) m_filterEventValHi = INT_MAX; if (m_filterEventPosLo < 0) m_filterEventPosLo = 0; if (m_filterEventPosHi < 0) m_filterEventPosHi = INT_MAX; m_filterEventLenLo = (m_filterEventLenLo < 0) ? (0) : (m_ppq * 4 * m_filterEventLenLo); m_filterEventLenHi = (m_filterEventLenHi < 0) ? (INT_MAX) : (m_ppq * 4 * m_filterEventLenHi); m_filterEventPosLo = (m_filterEventPosLo < 0) ? (0) : (m_ppq * 4 * m_filterEventPosLo); m_filterEventPosHi = (m_filterEventPosHi < 0) ? (INT_MAX) : (m_ppq * 4 * m_filterEventPosHi); m_filterEventPosRepeat = (m_filterEventPosRepeat < 0) ? (0) : (m_ppq * 4 * m_filterEventPosRepeat); return true; } } } return false; }
int EEL_Editor::GetCommentStateForLineStart(int line) { #ifdef START_ON_VARS_KEYWORD s_declaredFuncs.DeleteAll(); s_declaredVars.DeleteAll(); #endif m_indent_size=2; const bool uses_code_start_lines = !!is_code_start_line(NULL); int state=0; int x=0; if (uses_code_start_lines) { state=STATE_BEFORE_CODE; for (;;x++) { WDL_FastString *t = m_text.Get(x); if (!t || is_code_start_line(t->Get())) break; const char *p=t->Get(); if (!strnicmp(p,"tabsize:",8)) { int a = atoi(p+8); if (a>0 && a < 32) m_indent_size = a; } #ifdef START_ON_VARS_KEYWORD if (!strnicmp(p,"var",3) && isspace(p[3])) { const char *endp=p + t->GetLength(); const char *tok; int toklen; p+=4; while (NULL != (tok = sh_tokenize(&p,endp,&toklen,NULL))) { if (isalpha(tok[0]) || tok[0] == '_' || tok[0] == '#') { char buf[512]; if (toklen > sizeof(buf)-1) toklen=sizeof(buf)-1; lstrcpyn_safe(buf,tok,toklen+1); s_declaredVars.AddUnsorted(buf,1); } } } #endif } // scan backwards to find line starting with @ for (x=line;x>=0;x--) { WDL_FastString *t = m_text.Get(x); if (!t) break; if (is_code_start_line(t->Get())) { state=0; break; } } x++; } #ifdef START_ON_VARS_KEYWORD s_declaredVars.Resort(); #endif s_draw_parentokenstack.Resize(0,false); for (;x<line;x++) { WDL_FastString *t = m_text.Get(x); const char *p = t?t->Get():""; if (is_code_start_line(p)) { s_draw_parentokenstack.Resize(0,false); state=0; } else if (state != STATE_BEFORE_CODE) { const int ll=t?t->GetLength():0; const char *endp = p+ll; int toklen; const char *tok; while (NULL != (tok=sh_tokenize(&p,endp,&toklen,&state))) // eat all tokens, updating state { sh_func_ontoken(tok,toklen); sh_draw_parentokenstack_update(tok,toklen); } } } return state; }
// _type: 0=Post-Fader (Post-Pan), 1=Pre-FX, 2=deprecated, 3=Pre-Fader (Post-FX) // _undoMsg: NULL=no undo bool CueBuss(const char* _undoMsg, const char* _busName, int _type, bool _showRouting, int _soloDefeat, char* _trTemplatePath, bool _sendToMaster, int* _hwOuts) { if (!SNM_CountSelectedTracks(NULL, false)) return false; WDL_FastString tmplt; if (_trTemplatePath && (!FileOrDirExists(_trTemplatePath) || !LoadChunk(_trTemplatePath, &tmplt) || !tmplt.GetLength())) { char msg[SNM_MAX_PATH] = ""; lstrcpyn(msg, __LOCALIZE("Cue buss not created!\nNo track template file defined","sws_DLG_149"), sizeof(msg)); if (*_trTemplatePath) _snprintfSafe(msg, sizeof(msg), __LOCALIZE_VERFMT("Cue buss not created!\nTrack template not found (or empty): %s","sws_DLG_149"), _trTemplatePath); MessageBox(GetMainHwnd(), msg, __LOCALIZE("S&M - Error","sws_DLG_149"), MB_OK); return false; } bool updated = false; MediaTrack * cueTr = NULL; SNM_SendPatcher* p = NULL; for (int i=1; i <= GetNumTracks(); i++) // skip master { MediaTrack* tr = CSurf_TrackFromID(i, false); if (tr && *(int*)GetSetMediaTrackInfo(tr, "I_SELECTED", NULL)) { GetSetMediaTrackInfo(tr, "I_SELECTED", &g_i0); // add the buss track, done once! if (!cueTr) { InsertTrackAtIndex(GetNumTracks(), false); TrackList_AdjustWindows(false); cueTr = CSurf_TrackFromID(GetNumTracks(), false); GetSetMediaTrackInfo(cueTr, "P_NAME", (void*)_busName); p = new SNM_SendPatcher(cueTr); if (tmplt.GetLength()) { WDL_FastString chunk; MakeSingleTrackTemplateChunk(&tmplt, &chunk, true, true, false); ApplyTrackTemplate(cueTr, &chunk, false, false, p); } updated = true; } // add a send if (cueTr && p && tr != cueTr) AddReceiveWithVolPan(tr, cueTr, _type, p); } } if (cueTr && p) { // send to master/parent init if (!tmplt.GetLength()) { // solo defeat if (_soloDefeat) { char one[2] = "1"; updated |= (p->ParsePatch(SNM_SET_CHUNK_CHAR, 1, "TRACK", "MUTESOLO", 0, 3, one) > 0); } // master/parend send WDL_FastString mainSend; mainSend.SetFormatted(SNM_MAX_CHUNK_LINE_LENGTH, "MAINSEND %d 0", _sendToMaster?1:0); // adds hw outputs if (_hwOuts) { int monoHWCount=0; while (GetOutputChannelName(monoHWCount)) monoHWCount++; bool cr = false; for(int i=0; i<SNM_MAX_HW_OUTS; i++) { if (_hwOuts[i]) { if (!cr) { mainSend.Append("\n"); cr = true; } if (_hwOuts[i] >= monoHWCount) mainSend.AppendFormatted(32, "HWOUT %d ", (_hwOuts[i]-monoHWCount) | 1024); else mainSend.AppendFormatted(32, "HWOUT %d ", _hwOuts[i]-1); mainSend.Append("0 "); mainSend.AppendFormatted(20, "%.14f ", *(double*)GetConfigVar("defhwvol")); mainSend.Append("0.00000000000000 0 0 0 -1.00000000000000 -1\n"); } } if (!cr) mainSend.Append("\n"); // hot } // patch both updates (no break keyword here: new empty track) updated |= p->ReplaceLine("TRACK", "MAINSEND", 1, 0, mainSend.Get()); } p->Commit(); delete p; if (updated) { GetSetMediaTrackInfo(cueTr, "I_SELECTED", &g_i1); UpdateTimeline(); ScrollSelTrack(true, true); if (_showRouting) Main_OnCommand(40293, 0); if (_undoMsg) Undo_OnStateChangeEx2(NULL, _undoMsg, UNDO_STATE_ALL, -1); } } return updated; }
// supports folders, multi-selection and routings between tracks too void SaveSelTrackTemplates(bool _delItems, bool _delEnvs, WDL_FastString* _chunkOut) { if (!_chunkOut) return; WDL_PtrList<MediaTrack> tracks; // append selected track chunks (+ folders) ------------------------------- for (int i=0; i <= GetNumTracks(); i++) // incl. master { MediaTrack* tr = CSurf_TrackFromID(i, false); if (tr && *(int*)GetSetMediaTrackInfo(tr, "I_SELECTED", NULL)) { SaveSingleTrackTemplateChunk(tr, _chunkOut, _delItems, _delEnvs); tracks.Add(tr); // folder: save child templates WDL_PtrList<MediaTrack>* childTracks = GetChildTracks(tr); if (childTracks) { for (int j=0; j < childTracks->GetSize(); j++) { SaveSingleTrackTemplateChunk(childTracks->Get(j), _chunkOut, _delItems, _delEnvs); tracks.Add(childTracks->Get(j)); } i += childTracks->GetSize(); // skip children delete childTracks; } } } // update receives ids ---------------------------------------------------- // no break keyword used here: multiple tracks in the template SNM_ChunkParserPatcher p(_chunkOut); WDL_FastString line; int occurence = 0; int pos = p.Parse(SNM_GET_SUBCHUNK_OR_LINE, 1, "TRACK", "AUXRECV", occurence, 1, &line); while (pos > 0) { pos--; // see SNM_ChunkParserPatcher bool replaced = false; line.SetLen(line.GetLength()-1); // remove trailing '\n' LineParser lp(false); if (!lp.parse(line.Get()) && lp.getnumtokens() > 1) { int success, curId = lp.gettoken_int(1, &success); if (success) { MediaTrack* tr = CSurf_TrackFromID(curId+1, false); int newId = tracks.Find(tr); if (newId >= 0) { const char* p3rdTokenToEol = strchr(line.Get(), ' '); if (p3rdTokenToEol) p3rdTokenToEol = strchr((char*)(p3rdTokenToEol+1), ' '); if (p3rdTokenToEol) { WDL_FastString newRcv; newRcv.SetFormatted(SNM_MAX_CHUNK_LINE_LENGTH, "AUXRECV %d%s\n", newId, p3rdTokenToEol); replaced = p.ReplaceLine(pos, newRcv.Get()); if (replaced) occurence++; } } } } if (!replaced) replaced = p.ReplaceLine(pos, ""); if (!replaced) // skip, just in case.. occurence++; line.Set(""); pos = p.Parse(SNM_GET_SUBCHUNK_OR_LINE, 1, "TRACK", "AUXRECV", occurence, 1, &line); } }