racket/src/mred/wxme/wx_msnip.cxx
Eli Barzilay 8a2753efb8 2008 -> 2009
svn: r13001
2009-01-04 15:34:50 +00:00

1171 lines
25 KiB
C++

/*
* File: wx_msnip.cc
* Purpose: wxMediaSnip implementation
* Author: Matthew Flatt
* Created: 1995
* Copyright: (c) 2004-2009 PLT Scheme Inc.
* Copyright: (c) 1995, Matthew Flatt
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301 USA.
*/
#if defined(_MSC_VER) && defined(MZ_PRECISE_GC)
# include "wx.h"
#endif
#include "common.h"
#include "wx_media.h"
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <locale.h>
#include "wx_mpriv.h"
#include "wx_gcrct.h"
wxMediaSnip::wxMediaSnip(wxMediaBuffer *useme,
Bool border,
int lm, int tm, int rm, int bm,
int li, int ti, int ri, int bi,
double w, double W, double h, double H)
{
Bool istemp;
wxSnipClassList *scl;
#if USE_OLD_TYPE_SYSTEM
__type = wxTYPE_MEDIA_SNIP;
#endif
flags |= wxSNIP_HANDLES_EVENTS;
scl = &wxTheSnipClassList;
snipclass = scl->Find("wxmedia");
withBorder = border;
leftMargin = lm;
topMargin = tm;
rightMargin = rm;
bottomMargin = bm;
leftInset = li;
topInset = ti;
rightInset = ri;
bottomInset = bi;
minWidth = w;
maxWidth = W;
minHeight = h;
maxHeight = H;
if (useme && !useme->GetAdmin()) {
me = useme;
} else {
me = wxsMakeMediaEdit();
}
{
wxMediaSnipMediaAdmin *msma;
msma = new WXGC_PTRS wxMediaSnipMediaAdmin(this);
myAdmin = msma;
}
if (!me->GetFilename(&istemp) || istemp)
/* Turn on flag to mirror filename: */
flags |= wxSNIP_USES_BUFFER_PATH;
me->OwnCaret(FALSE);
}
wxMediaSnip::~wxMediaSnip()
{
#if 1
/* The only way a snip should be deleted if by GC, and it wouldn't
get GC'd if the editor isn't also going to be GCd. It's important
*not* to call SetAdmin(), because that can trigger Scheme
code. */
DELETE_OBJ me;
me = NULL;
#else
if (me) {
if (me->GetAdmin() == myAdmin)
me->SetAdmin(NULL);
}
#endif
DELETE_OBJ myAdmin;
}
void wxMediaSnip::SetAdmin(wxSnipAdmin *a)
{
if (PTRNE(a, admin)) {
wxSnip::SetAdmin(a);
if (me) {
if (a) {
if (me->GetAdmin())
me = NULL; /* traitor! - get rid of it */
else
me->SetAdmin(myAdmin);
} else
me->SetAdmin(NULL);
}
}
if (admin && (flags & wxSNIP_USES_BUFFER_PATH)) {
/* Propogate a filename change: */
Bool istemp;
if (me && (!me->GetFilename(&istemp) || istemp)) {
wxMediaBuffer *b;
b = admin->GetMedia();
if (b) {
char *filename;
filename = b->GetFilename();
if (filename)
me->SetFilename(filename, TRUE);
}
} else
flags -= wxSNIP_USES_BUFFER_PATH; /* Turn off the flag; not needed */
}
}
void wxMediaSnip::SetMedia(wxMediaBuffer *b)
{
if (me == b)
return;
if (me && admin)
me->SetAdmin(NULL);
me = b;
if (b) {
if (b->GetAdmin()) {
me = NULL;
return;
} else if (admin) {
me->SetAdmin(myAdmin);
}
}
if (admin)
admin->Resized(this, TRUE);
}
wxMediaBuffer *wxMediaSnip::GetThisMedia(void)
{
return me;
}
wxCursor *wxMediaSnip::AdjustCursor(wxDC *dc, double x, double y,
double, double, wxMouseEvent *event)
{
wxMSMA_SnipDrawState *save;
wxCursor *c;
if (!me)
return NULL;
save = new WXGC_PTRS wxMSMA_SnipDrawState;
myAdmin->SaveState(save, dc, x, y);
c = me->AdjustCursor(event);
myAdmin->RestoreState(save);
return c;
}
void wxMediaSnip::OnEvent(wxDC *dc, double x, double y,
double, double, wxMouseEvent *event)
{
wxMSMA_SnipDrawState *save;
if (!me) return;
save = new WXGC_PTRS wxMSMA_SnipDrawState;
myAdmin->SaveState(save, dc, x, y);
me->OnEvent(event);
myAdmin->RestoreState(save);
}
void wxMediaSnip::OnChar(wxDC *dc, double x, double y,
double, double, wxKeyEvent *event)
{
wxMSMA_SnipDrawState *save;
if (!me) return;
save = new WXGC_PTRS wxMSMA_SnipDrawState;
myAdmin->SaveState(save, dc, x, y);
me->OnChar(event);
myAdmin->RestoreState(save);
}
void wxMediaSnip::OwnCaret(Bool ownit)
{
if (me)
me->OwnCaret(ownit);
}
void wxMediaSnip::BlinkCaret(wxDC *dc, double x, double y)
{
if (me) {
wxMSMA_SnipDrawState *save;
save = new WXGC_PTRS wxMSMA_SnipDrawState;
myAdmin->SaveState(save, dc, x, y);
me->BlinkCaret();
myAdmin->RestoreState(save);
}
}
void wxMediaSnip::DoEdit(int op, Bool recursive, long time)
{
if (me)
me->DoEdit(op, recursive, time);
}
Bool wxMediaSnip::CanEdit(int op, Bool recursive)
{
if (me)
return me->CanEdit(op, recursive);
else
return FALSE;
}
void wxMediaSnip::DoFont(int op, Bool recursive)
{
if (me)
me->DoFont(op, recursive);
}
Bool wxMediaSnip::Match(wxSnip *)
{
return FALSE;
}
void wxMediaSnip::SizeCacheInvalid(void)
{
if (me)
me->SizeCacheInvalid();
}
wxchar *wxMediaSnip::GetText(long offset, long num, Bool flat, long *got)
{
if (offset >= 1 || !num) {
if (got) *got = 0;
return wx_empty_wxstr;
}
if (!flat) {
wxchar *s;
s = new WXGC_ATOMIC wxchar[2];
s[0] = '.';
s[1] = 0;
if (got) *got = 1;
return s;
} else if (me)
return me->GetFlattenedText(got);
else
return wx_empty_wxstr;
}
void wxMediaSnip::GetExtent(wxDC *dc,
double x, double y,
double *w, double *h,
double *_descent, double *_space,
double *lspace, double *rspace)
{
wxMSMA_SnipDrawState *save;
double descent, space, origH, dummyH;
save = new WXGC_PTRS wxMSMA_SnipDrawState;
myAdmin->SaveState(save, dc, x, y);
if (!h && alignTopLine)
h = &dummyH;
if (me)
me->GetExtent(w, h);
else {
if (w)
*w = 0;
if (h)
*h = 0;
}
origH = alignTopLine ? *h : 0.0;
if (w) {
if (me && (me->bufferType == wxEDIT_BUFFER)) {
if (tightFit)
(*w) -= CURSOR_WIDTH;
else
--(*w); /* It still looks better to subtract 1 */
if (*w < 0)
*w = 0;
}
if (*w < minWidth)
*w = minWidth;
else if (maxWidth > 0 && *w > maxWidth)
*w = maxWidth;
(*w) += rightMargin + leftMargin;
}
if (h) {
if (me && (me->bufferType == wxEDIT_BUFFER)) {
if (tightFit) {
(*h) -= ((wxMediaEdit *)me)->GetLineSpacing();
if (*h < 0)
*h = 0;
}
}
if (*h < minHeight)
*h = minHeight;
else if (maxHeight > 0 && *h > maxHeight)
*h = maxHeight;
(*h) += topMargin + bottomMargin;
}
{
descent = (me ? me->GetDescent() : 0.0) + bottomMargin;
if (me && (me->bufferType == wxEDIT_BUFFER)) {
if (alignTopLine)
descent = origH - ((wxMediaEdit *)me)->GetTopLineBase() + bottomMargin;
if (tightFit) {
descent -= ((wxMediaEdit *)me)->GetLineSpacing();
if (descent < 0)
descent = 0;
}
}
}
space = (me ? me->GetSpace() : 0.0) + topMargin;
if (maxHeight > 0 && (descent + space >= maxHeight + topMargin + bottomMargin)) {
/* Just give up on spaces in this case: */
space = topMargin;
descent = bottomMargin;
}
if (_descent)
*_descent = descent;
if (_space)
*_space = space;
if (lspace)
*lspace = leftMargin;
if (rspace)
*rspace = rightMargin;
myAdmin->RestoreState(save);
}
void wxMediaSnip::Draw(wxDC *dc, double x, double y,
double left, double top, double right, double bottom,
double WXUNUSED(dx), double WXUNUSED(dy),
int show_caret)
{
double w, h, r, b, orig_x, orig_y;
double t, l;
wxColour *bgColor = wxWHITE;
wxMSMA_SnipDrawState *save;
save = new WXGC_PTRS wxMSMA_SnipDrawState;
myAdmin->SaveState(save, dc, x, y);
if (me) {
w = h = 0.0;
me->GetExtent(&w, &h);
if (me && (me->bufferType == wxEDIT_BUFFER)) {
if (tightFit)
w -= CURSOR_WIDTH;
else
--w; /* It still looks better to subtract 1 */
if (w < 0)
w = 0;
}
if (me && (me->bufferType == wxEDIT_BUFFER)) {
if (tightFit) {
h -= ((wxMediaEdit *)me)->GetLineSpacing();
if (h < 0)
h = 0;
}
}
} else
w = h = 0.0;
if (w < minWidth)
w = minWidth;
else if (maxWidth > 0 && w > maxWidth)
w = maxWidth;
if (h < minHeight)
h = minHeight;
else if (maxHeight > 0 && h > maxHeight)
h = maxHeight;
orig_x = x;
orig_y = y;
x += leftMargin;
y += topMargin;
r = x + w;
b = y + h;
l = ((x > left) ? x : left);
t = ((y > top) ? y : top);
r = ((r < right) ? r : right);
b = ((b < bottom) ? b : bottom);
if (useStyleBG) {
if (style->GetTransparentTextBacking()) {
bgColor = NULL;
} else {
wxBrush *saveb, *fill;
wxPen *savep, *transPen;
bgColor = style->GetBackground();
l = orig_x + leftInset;
t = orig_y + topInset;
r = l + (w + leftMargin + rightMargin - (leftInset + rightInset)) - 1;
b = t + (h + topMargin + bottomMargin - (topInset + bottomInset)) - 1;
transPen = wxThePenList->FindOrCreatePen(bgColor, 0, wxTRANSPARENT);
fill = wxTheBrushList->FindOrCreateBrush(bgColor, wxSOLID);
savep = dc->GetPen();
saveb = dc->GetBrush();
dc->SetPen(transPen);
dc->SetBrush(fill);
dc->DrawRectangle(l, t, r - l, b - t);
dc->SetBrush(saveb);
dc->SetPen(savep);
}
}
if (me)
me->Refresh(l - x, t - y, r - l, b - t, show_caret, bgColor);
if (withBorder) {
double mt, ml, mb, mr;
l = orig_x + leftInset;
t = orig_y + topInset;
r = l + (w + leftMargin + rightMargin - (leftInset + rightInset)) - 1;
b = t + (h + topMargin + bottomMargin - (topInset + bottomInset)) - 1;
ml = ((l > left) ? ((l < right) ? l : right) : left);
mr = ((r > left) ? ((r < right) ? r : right) : left);
mt = ((t > top) ? ((t < bottom) ? t : bottom) : top);
mb = ((b > top) ? ((b < bottom) ? b : bottom) : top);
if (l >= left && l < right && mt < mb + GC_LINE_EXTEND)
dc->DrawLine(l, mt, l, mb + GC_LINE_EXTEND);
if (r >= left && r < right && mt < mb + GC_LINE_EXTEND)
dc->DrawLine(r, mt, r, mb + GC_LINE_EXTEND);
if (t >= top && t < bottom && ml < mr + GC_LINE_EXTEND)
dc->DrawLine(ml, t, mr + GC_LINE_EXTEND, t);
if (b >= top && b < bottom && ml < mr + GC_LINE_EXTEND)
dc->DrawLine(ml, b, mr + GC_LINE_EXTEND, b);
}
myAdmin->RestoreState(save);
}
wxSnip *wxMediaSnip::Copy(void)
{
wxMediaSnip *ms;
wxMediaBuffer *mb;
mb = (me ? me->CopySelf() : (wxMediaBuffer *)NULL);
ms = wxsMakeMediaSnip(mb,
withBorder,
leftMargin, topMargin,
rightMargin, bottomMargin,
leftInset, topInset,
rightInset, bottomInset,
minWidth, maxWidth,
minHeight, maxHeight);
/* Copy core snip info: */
wxSnip::Copy(ms);
ms->tightFit = tightFit;
ms->alignTopLine = alignTopLine;
if (!me)
ms->SetMedia(NULL);
return ms;
}
void wxMediaSnip::Write(wxMediaStreamOut *f)
{
Bool wb = withBorder, tf = tightFit, ta = alignTopLine, usbg = useStyleBG;
f->Put((me ? me->bufferType : 0));
f->Put(wb);
f->Put(leftMargin);
f->Put(topMargin);
f->Put(rightMargin);
f->Put(bottomMargin);
f->Put(leftInset);
f->Put(topInset);
f->Put(rightInset);
f->Put(bottomInset);
f->Put(minWidth);
f->Put(maxWidth);
f->Put(minHeight);
f->Put(maxHeight);
f->Put(tf);
f->Put(ta);
f->Put(usbg);
if (me)
me->WriteToFile(f);
}
void wxMediaSnip::SetMaxWidth(double w)
{
maxWidth = w;
if (admin)
admin->Resized(this, TRUE);
}
void wxMediaSnip::SetMinWidth(double w)
{
minWidth = w;
if (admin)
admin->Resized(this, TRUE);
}
void wxMediaSnip::SetMaxHeight(double h)
{
maxHeight = h;
if (admin)
admin->Resized(this, TRUE);
}
void wxMediaSnip::SetMinHeight(double h)
{
minHeight = h;
if (admin)
admin->Resized(this, TRUE);
}
double wxMediaSnip::GetMaxWidth(void) { return maxWidth; }
double wxMediaSnip::GetMaxHeight(void) { return maxHeight; }
double wxMediaSnip::GetMinWidth(void) { return minWidth; }
double wxMediaSnip::GetMinHeight(void) { return minHeight; }
Bool wxMediaSnip::GetTightTextFit(void)
{
return tightFit;
}
void wxMediaSnip::SetTightTextFit(Bool t)
{
tightFit = (t ? TRUE : FALSE);
if (admin)
admin->Resized(this, TRUE);
}
Bool wxMediaSnip::GetAlignTopLine(void)
{
return alignTopLine;
}
void wxMediaSnip::SetAlignTopLine(Bool t)
{
alignTopLine = (t ? TRUE : FALSE);
if (admin)
admin->Resized(this, TRUE);
}
void wxMediaSnip::UseStyleBG(Bool useit)
{
if ((useStyleBG ? 1 : 0) != (useit ? 1 : 0)) {
useStyleBG = (useit ? TRUE : FALSE);
RequestRefresh();
}
}
Bool wxMediaSnip::StyleBGUsed()
{
return useStyleBG;
}
Bool wxMediaSnip::Resize(double w, double h)
{
w -= leftMargin + rightMargin;
h -= topMargin + bottomMargin;
if (w < 0)
w = 0;
if (h < 0)
h = 0;
minWidth = maxWidth = w;
minHeight = maxHeight = h;
if (me) {
me->SetMaxWidth(w);
me->SetMinWidth(w);
}
if (admin)
admin->Resized(this, TRUE);
return TRUE;
}
void wxMediaSnip::RequestRefresh()
{
if (admin) {
wxDC *dc;
double w, h;
dc = admin->GetDC();
if (dc) {
w = h = 0.0;
GetExtent(dc, 0, 0, &w, &h);
admin->NeedsUpdate(this, leftInset, topInset,
w + rightMargin - rightInset,
h + bottomMargin - bottomInset);
}
}
}
void wxMediaSnip::ShowBorder(Bool show)
{
if ((withBorder ? 1 : 0) != (show ? 1 : 0)) {
withBorder = (show ? TRUE : FALSE);
RequestRefresh();
}
}
Bool wxMediaSnip::BorderVisible()
{
return withBorder;
}
void wxMediaSnip::SetMargin(int lm, int tm, int rm, int bm)
{
leftMargin = lm;
topMargin = tm;
rightMargin = rm;
bottomMargin = bm;
if (admin)
admin->Resized(this, TRUE);
}
void wxMediaSnip::GetMargin(int *lm, int *tm, int *rm, int *bm)
{
*lm = leftMargin;
*tm = topMargin;
*rm = rightMargin;
*bm = bottomMargin;
}
void wxMediaSnip::SetInset(int lm, int tm, int rm, int bm)
{
leftMargin = lm;
topMargin = tm;
rightMargin = rm;
bottomMargin = bm;
if (admin) {
wxDC *dc;
double w, h;
dc = admin->GetDC();
if (dc) {
w = h = 0.0;
GetExtent(dc, 0, 0, &w, &h);
admin->NeedsUpdate(this, 0, 0,
w + rightMargin + leftMargin,
h + bottomMargin + topMargin);
}
}
}
void wxMediaSnip::GetInset(int *li, int *ti, int *ri, int *bi)
{
*li = leftInset;
*ti = topInset;
*ri = rightInset;
*bi = bottomInset;
}
long wxMediaSnip::GetNumScrollSteps()
{
return (me ? me->NumScrollLines() : 1);
}
long wxMediaSnip::FindScrollStep(double y)
{
return (me ? me->FindScrollLine(y - topMargin) : 0);
}
double wxMediaSnip::GetScrollStepOffset(long i)
{
return (me ? me->ScrollLineLocation(i) + topMargin : 0);
}
void wxMediaSnip::SetUnmodified()
{
if (me)
me->SetModified(FALSE);
}
/****************************************************************/
wxMediaSnipMediaAdmin::wxMediaSnipMediaAdmin(wxMediaSnip *s)
{
#if USE_OLD_TYPE_SYSTEM
__type = wxTYPE_MEDIA_SNIP_MEDIA_ADMIN;
#endif
snip = s;
state = new WXGC_PTRS wxMSMA_SnipDrawState;
state->drawing = 0;
WXGC_IGNORE(state, state->dc);
}
wxMediaSnipMediaAdmin::~wxMediaSnipMediaAdmin()
{
state->dc = NULL;
}
wxDC *wxMediaSnipMediaAdmin::GetDC(double *xp, double *yp)
{
if (state->drawing) {
if (xp)
*xp = -state->x;
if (yp)
*yp = -state->y;
} else {
if (xp)
*xp = 0;
if (yp)
*yp = 0;
}
if (state->drawing)
return state->dc;
else {
wxSnipAdmin *sadmin;
sadmin = snip->GetAdmin();
if (sadmin)
return sadmin->GetDC();
else
return NULL;
}
}
void wxMediaSnipMediaAdmin::SaveState(wxMSMA_SnipDrawState *save, wxDC *dc,
double x, double y)
{
save->drawing = state->drawing;
save->dc = state->dc;
save->x = state->x;
save->y = state->y;
state->drawing = TRUE;
state->x = x + snip->leftMargin;
state->y = y + snip->topMargin;
state->dc = dc;
}
void wxMediaSnipMediaAdmin::RestoreState(wxMSMA_SnipDrawState *saved)
{
state->drawing = saved->drawing;
state->dc = saved->dc;
state->x = saved->x;
state->y = saved->y;
}
void wxMediaSnipMediaAdmin::GetView(double *x, double *y, double *w, double *h,
Bool full)
{
wxSnipAdmin *sadmin;
sadmin = snip->GetAdmin();
if (!sadmin) {
if (x) *x = 0;
if (y) *y = 0;
if (w) *w = 0;
if (h) *h = 0;
return;
}
if (full) {
sadmin->GetView(x, y, w, h, NULL);
} else {
double sx, sy, sw, sh;
sadmin->GetView(&sx, &sy, &sw, &sh, snip);
if (x) {
*x = sx - snip->leftMargin;
if (*x < 0)
*x = 0;
}
if (y) {
*y = sy - snip->topMargin;
if (*y < 0)
*y = 0;
}
if (w || h) {
if (sw || sh) {
/* w and h might be too big due to margins - but
they might be small enough already because
part of the snip itself is not viewed. */
double rw, rh;
/* We want the internal, non-overridden method: */
snip->wxMediaSnip::GetExtent(state->dc, 0, 0, &rw, &rh);
/* remember: sx and sy are in snip coordinates */
if (w) {
double leftMargin, rightMargin;
leftMargin = snip->leftMargin - sx;
if (leftMargin < 0)
leftMargin = 0;
sw -= leftMargin;
rw -= snip->leftMargin;
rightMargin = snip->rightMargin - (rw - sw);
if (rightMargin < 0)
rightMargin = 0;
sw -= rightMargin;
if (sw < 0) sw = 0;
*w = sw;
}
if (h) {
double topMargin, bottomMargin;
topMargin = snip->topMargin - sy;
if (topMargin < 0)
topMargin = 0;
sh -= topMargin;
rh -= snip->topMargin;
bottomMargin = snip->bottomMargin - (rh - sh);
if (bottomMargin < 0)
bottomMargin = 0;
sh -= bottomMargin;
if (sh < 0) sh = 0;
*h = sh;
}
} else {
if (w) *w = 0;
if (h) *h = 0;
}
}
}
}
Bool wxMediaSnipMediaAdmin::ScrollTo(double localx, double localy, double w, double h,
Bool refresh, int bias)
{
wxSnipAdmin *sadmin;
sadmin = snip->GetAdmin();
if (sadmin)
return sadmin->ScrollTo(snip, localx + snip->leftMargin,
localy + snip->topMargin,
w, h, refresh, bias);
else
return FALSE;
}
void wxMediaSnipMediaAdmin::GrabCaret(int dist)
{
wxSnipAdmin *sadmin;
sadmin = snip->GetAdmin();
if (sadmin)
sadmin->SetCaretOwner(snip, dist);
}
void wxMediaSnipMediaAdmin::Resized(Bool redraw_now)
{
wxSnipAdmin *sadmin;
sadmin = snip->GetAdmin();
if (sadmin)
sadmin->Resized(snip, redraw_now);
}
void wxMediaSnipMediaAdmin::NeedsUpdate(double localx, double localy,
double w, double h)
{
wxSnipAdmin *sadmin;
sadmin = snip->GetAdmin();
if (sadmin)
sadmin->NeedsUpdate(snip,
localx + snip->leftMargin,
localy + snip->topMargin,
w, h);
}
void wxMediaSnipMediaAdmin::UpdateCursor()
{
wxSnipAdmin *sadmin;
sadmin = snip->GetAdmin();
if (sadmin)
sadmin->UpdateCursor();
}
Bool wxMediaSnipMediaAdmin::PopupMenu(void *m, double x, double y)
{
wxSnipAdmin *sadmin;
sadmin = snip->GetAdmin();
if (sadmin)
return sadmin->PopupMenu(m, snip,
x + snip->leftMargin,
y + snip->topMargin);
else
return FALSE;
}
Bool wxMediaSnipMediaAdmin::DelayRefresh()
{
wxSnipAdmin *sadmin;
sadmin = snip->GetAdmin();
if (!sadmin)
return 1;
if (sadmin->__type == wxTYPE_MEDIA_SNIP_ADMIN) {
wxMediaBuffer *b;
b = ((wxStandardSnipAdmin *)sadmin)->GetMedia();
return b->RefreshDelayed();
} else
return 0;
}
void wxMediaSnipMediaAdmin::Modified(Bool modified)
{
wxSnipAdmin *sadmin;
sadmin = snip->GetAdmin();
if (sadmin)
sadmin->Modified(snip, modified);
}
/************************************************************************/
extern wxMediaBuffer *objscheme_unbundle_wxMediaBuffer(Scheme_Object *, const char*, int);
#define GET_EDIT(buf) ((buf->bufferType == wxEDIT_BUFFER) ? (wxMediaEdit *)buf : NULL)
#define GET_BUF(bv) objscheme_unbundle_wxMediaBuffer((Scheme_Object *)vb, NULL, 0)
#define edf(name, action) \
static Bool ed_##name(void *vb, wxEvent *, void *) \
{ wxMediaBuffer *buf; wxMediaEdit *b; \
buf = GET_BUF(vb); \
b = GET_EDIT(buf); \
if (!b) return FALSE; \
b->action; return TRUE; } \
edf(right, MovePosition(WXK_RIGHT))
edf(left, MovePosition(WXK_LEFT))
edf(up, MovePosition(WXK_UP))
edf(down, MovePosition(WXK_DOWN))
edf(pageup, MovePosition(WXK_UP, FALSE, wxMOVE_PAGE))
edf(pagedown, MovePosition(WXK_DOWN, FALSE, wxMOVE_PAGE))
edf(rightword, MovePosition(WXK_RIGHT, FALSE, wxMOVE_WORD))
edf(leftword, MovePosition(WXK_LEFT, FALSE, wxMOVE_WORD))
edf(selectright, MovePosition(WXK_RIGHT, TRUE))
edf(selectleft, MovePosition(WXK_LEFT, TRUE))
edf(selectup, MovePosition(WXK_UP, TRUE))
edf(selectdown, MovePosition(WXK_DOWN, TRUE))
edf(selectpageup, MovePosition(WXK_UP, TRUE, wxMOVE_PAGE))
edf(selectpagedown, MovePosition(WXK_DOWN, TRUE, wxMOVE_PAGE))
edf(selectrightword, MovePosition(WXK_RIGHT, TRUE, wxMOVE_WORD))
edf(selectleftword, MovePosition(WXK_LEFT, TRUE, wxMOVE_WORD))
edf(startofline, MovePosition(WXK_LEFT, FALSE, wxMOVE_LINE))
edf(endofline, MovePosition(WXK_RIGHT, FALSE, wxMOVE_LINE))
edf(home, MovePosition(WXK_HOME))
edf(end, MovePosition(WXK_END))
edf(selecttostartofline, MovePosition(WXK_LEFT, TRUE, wxMOVE_LINE))
edf(selecttoendofline, MovePosition(WXK_RIGHT, TRUE, wxMOVE_LINE))
edf(selecttohome, MovePosition(WXK_HOME, TRUE))
edf(selecttoend, MovePosition(WXK_END, TRUE))
edf(clear, Erase())
edf(delete, Delete())
edf(pastenext, PasteNext())
static Bool ed_deletenext(void *vb, wxEvent *, void *)
{
long s, e;
wxMediaEdit *edit;
wxMediaBuffer *buf;
buf = GET_BUF(vb);
edit = GET_EDIT(buf);
if (!edit) return FALSE;
edit->GetPosition(&s, &e);
if (s != e)
edit->Delete();
else
edit->Delete(s, s + 1);
return TRUE;
}
static Bool ed_deletenextword(void *vb, wxEvent *event, void *)
{
wxMediaEdit *edit;
wxMediaBuffer *buf;
buf = GET_BUF(vb);
edit = GET_EDIT(buf);
if (!edit) return FALSE;
edit->BeginEditSequence();
ed_selectrightword(edit, event, NULL);
ed_delete(edit, event, NULL);
edit->EndEditSequence();
return TRUE;
}
static Bool ed_deleteprevword(void *vb, wxEvent *event, void *)
{
wxMediaEdit *edit;
wxMediaBuffer *buf;
buf = GET_BUF(vb);
edit = GET_EDIT(buf);
if (!edit) return FALSE;
edit->BeginEditSequence();
ed_selectleftword(edit, event, NULL);
ed_delete(edit, event, NULL);
edit->EndEditSequence();
return TRUE;
}
static Bool ed_deleteline(void *vb, wxEvent *event, void *)
{
wxMediaEdit *edit;
wxMediaBuffer *buf;
buf = GET_BUF(vb);
edit = GET_EDIT(buf);
if (!edit) return FALSE;
edit->BeginEditSequence();
ed_startofline(edit, event, NULL);
ed_selecttoendofline(edit, event, NULL);
ed_delete(edit, event, NULL);
edit->EndEditSequence();
return TRUE;
}
void wxMediaEdit::AddEditorFunctions(wxKeymap *tab)
{
wxAddMediaEditorFunctions(tab);
}
void wxAddMediaEditorFunctions(wxKeymap *tab)
{
#define setf(name, func) tab->AddFunction(name, ed_##func, NULL)
setf("forward-character", right);
setf("backward-character", left);
setf("previous-line", up);
setf("next-line", down);
setf("previous-page", pageup);
setf("next-page", pagedown);
setf("forward-word", rightword);
setf("backward-word", leftword);
setf("forward-select", selectright);
setf("backward-select", selectleft);
setf("select-down", selectdown);
setf("select-up", selectup);
setf("select-page-up", selectpageup);
setf("select-page-down", selectpagedown);
setf("forward-select-word", selectrightword);
setf("backward-select-word", selectleftword);
setf("beginning-of-file", home);
setf("end-of-file", end);
setf("beginning-of-line", startofline);
setf("end-of-line", endofline);
setf("select-to-beginning-of-file", selecttohome);
setf("select-to-end-of-file", selecttoend);
setf("select-to-beginning-of-line", selecttostartofline);
setf("select-to-end-of-line", selecttoendofline);
setf("delete-previous-character", delete);
setf("delete-next-character", deletenext);
setf("clear-buffer", clear);
setf("delete-next-word", deletenextword);
setf("delete-previous-word", deleteprevword);
setf("delete-line", deleteline);
setf("paste-next", pastenext);
wxAddMediaBufferFunctions(tab);
}
/*************************************************************/
wxMediaWordbreakMap::wxMediaWordbreakMap()
{
int i;
char *old;
usage = 0;
memset(map, 0, sizeof(map));
/* Use default locale... */
old = setlocale(LC_CTYPE, NULL);
old = copystring(old);
setlocale(LC_CTYPE, "");
for (i = 0; i < 256; i++) {
if (isalnum(i))
map[i] = wxBREAK_FOR_CARET | wxBREAK_FOR_LINE | wxBREAK_FOR_SELECTION;
else if ((i >= 128) || !isspace(i))
map[i] = wxBREAK_FOR_LINE;
}
setlocale(LC_CTYPE, old);
map[(int)'-'] -= wxBREAK_FOR_LINE;
}
void wxMediaWordbreakMap::SetMap(int ch, int mask)
{
if ((ch >= 0) && (ch <= 255))
map[ch] = mask;
}
int wxMediaWordbreakMap::GetMap(int ch)
{
if ((ch >= 0) && (ch <= 255))
return map[ch];
else
return 0;
}