⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scintillagtk.cxx

📁 一个可以提供语法高亮显示的编辑器
💻 CXX
📖 第 1 页 / 共 5 页
字号:
			FullPaint();
		}
	}
}

void ScintillaGTK::Resize(int width, int height) {
	//Platform::DebugPrintf("Resize %d %d\n", width, height);
	//printf("Resize %d %d\n", width, height);

	// Not always needed, but some themes can have different sizes of scrollbars
	scrollBarWidth = GTK_WIDGET(PWidget(scrollbarv))->requisition.width;
	scrollBarHeight = GTK_WIDGET(PWidget(scrollbarh))->requisition.height;

	// These allocations should never produce negative sizes as they would wrap around to huge
	// unsigned numbers inside GTK+ causing warnings.
	bool showSBHorizontal = horizontalScrollBarVisible && (wrapState == eWrapNone);
	int horizontalScrollBarHeight = scrollBarHeight;
	if (!showSBHorizontal)
		horizontalScrollBarHeight = 0;
	int verticalScrollBarHeight = scrollBarWidth;
	if (!verticalScrollBarVisible)
		verticalScrollBarHeight = 0;

	GtkAllocation alloc;
	alloc.x = 0;
	if (showSBHorizontal) {
		alloc.y = height - scrollBarHeight;
		alloc.width = Platform::Maximum(1, width - scrollBarWidth) + 1;
		alloc.height = horizontalScrollBarHeight;
	} else {
		alloc.y = -scrollBarHeight;
		alloc.width = 0;
		alloc.height = 0;
	}
	gtk_widget_size_allocate(GTK_WIDGET(PWidget(scrollbarh)), &alloc);

	alloc.y = 0;
	if (verticalScrollBarVisible) {
		alloc.x = width - scrollBarWidth;
		alloc.width = scrollBarWidth;
		alloc.height = Platform::Maximum(1, height - scrollBarHeight) + 1;
		if (!showSBHorizontal)
			alloc.height += scrollBarWidth-1;
	} else {
		alloc.x = -scrollBarWidth;
		alloc.width = 0;
		alloc.height = 0;
	}
	gtk_widget_size_allocate(GTK_WIDGET(PWidget(scrollbarv)), &alloc);
	if (GTK_WIDGET_MAPPED(PWidget(wMain))) {
		ChangeSize();
	}

	alloc.x = 0;
	alloc.y = 0;
	alloc.width = Platform::Maximum(1, width - scrollBarWidth);
	alloc.height = Platform::Maximum(1, height - scrollBarHeight);
	if (!showSBHorizontal)
		alloc.height += scrollBarWidth;
	gtk_widget_size_allocate(GTK_WIDGET(PWidget(wText)), &alloc);
}

static void SetAdjustmentValue(GtkObject *object, int value) {
	GtkAdjustment *adjustment = GTK_ADJUSTMENT(object);
	int maxValue = static_cast<int>(
		adjustment->upper - adjustment->page_size);
	if (value > maxValue)
		value = maxValue;
	if (value < 0)
		value = 0;
	gtk_adjustment_set_value(adjustment, value);
}

gint ScintillaGTK::PressThis(GdkEventButton *event) {
	//Platform::DebugPrintf("Press %x time=%d state = %x button = %x\n",this,event->time, event->state, event->button);
	// Do not use GTK+ double click events as Scintilla has its own double click detection
	if (event->type != GDK_BUTTON_PRESS)
		return FALSE;

	evbtn = *event;
	Point pt;
	pt.x = int(event->x);
	pt.y = int(event->y);
	PRectangle rcClient = GetClientRectangle();
	//Platform::DebugPrintf("Press %0d,%0d in %0d,%0d %0d,%0d\n",
	//	pt.x, pt.y, rcClient.left, rcClient.top, rcClient.right, rcClient.bottom);
	if ((pt.x > rcClient.right) || (pt.y > rcClient.bottom)) {
		Platform::DebugPrintf("Bad location\n");
		return FALSE;
	}

	bool ctrl = (event->state & GDK_CONTROL_MASK) != 0;

	gtk_widget_grab_focus(PWidget(wMain));
	if (event->button == 1) {
		//ButtonDown(pt, event->time,
		//	event->state & GDK_SHIFT_MASK,
		//	event->state & GDK_CONTROL_MASK,
		//	event->state & GDK_MOD1_MASK);
		// Instead of sending literal modifiers use control instead of alt
		// This is because all the window managers seem to grab alt + click for moving
		ButtonDown(pt, event->time,
		                    (event->state & GDK_SHIFT_MASK) != 0,
		                    (event->state & GDK_CONTROL_MASK) != 0,
		                    (event->state & GDK_CONTROL_MASK) != 0);
	} else if (event->button == 2) {
		// Grab the primary selection if it exists
		Position pos = PositionFromLocation(pt);
		if (OwnPrimarySelection() && primary.s == NULL)
			CopySelectionRange(&primary);

		SetSelection(pos, pos);
		gtk_selection_convert(GTK_WIDGET(PWidget(wMain)), GDK_SELECTION_PRIMARY,
		                      gdk_atom_intern("STRING", FALSE), event->time);
	} else if (event->button == 3) {
		if (displayPopupMenu) {
			// PopUp menu
			// Convert to screen
			int ox = 0;
			int oy = 0;
			gdk_window_get_origin(PWidget(wMain)->window, &ox, &oy);
			ContextMenu(Point(pt.x + ox, pt.y + oy));
		} else {
			return FALSE;
		}
	} else if (event->button == 4) {
		// Wheel scrolling up (only xwin gtk does it this way)
		if (ctrl)
			SetAdjustmentValue(adjustmenth, (xOffset / 2) - 6);
		else
			SetAdjustmentValue(adjustmentv, topLine - 3);
	} else if (event->button == 5) {
		// Wheel scrolling down (only xwin gtk does it this way)
		if (ctrl)
			SetAdjustmentValue(adjustmenth, (xOffset / 2) + 6);
		else
			SetAdjustmentValue(adjustmentv, topLine + 3);
	}
#if GTK_MAJOR_VERSION >= 2
	return TRUE;
#else
	return FALSE;
#endif
}

gint ScintillaGTK::Press(GtkWidget *widget, GdkEventButton *event) {
	if (event->window != widget->window)
		return FALSE;
	ScintillaGTK *sciThis = ScintillaFromWidget(widget);
	return sciThis->PressThis(event);
}

gint ScintillaGTK::MouseRelease(GtkWidget *widget, GdkEventButton *event) {
	ScintillaGTK *sciThis = ScintillaFromWidget(widget);
	//Platform::DebugPrintf("Release %x %d %d\n",sciThis,event->time,event->state);
	if (!sciThis->HaveMouseCapture())
		return FALSE;
	if (event->button == 1) {
		Point pt;
		pt.x = int(event->x);
		pt.y = int(event->y);
		//Platform::DebugPrintf("Up %x %x %d %d %d\n",
		//	sciThis,event->window,event->time, pt.x, pt.y);
		if (event->window != PWidget(sciThis->wMain)->window)
			// If mouse released on scroll bar then the position is relative to the
			// scrollbar, not the drawing window so just repeat the most recent point.
			pt = sciThis->ptMouseLast;
		sciThis->ButtonUp(pt, event->time, (event->state & 4) != 0);
	}
	return FALSE;
}

// win32gtk has a special wheel mouse event for whatever reason and doesn't
// use the button4/5 trick used under X windows.
#if PLAT_GTK_WIN32 || (GTK_MAJOR_VERSION >= 2)
gint ScintillaGTK::ScrollEvent(GtkWidget *widget,
                               GdkEventScroll *event) {
	ScintillaGTK *sciThis = ScintillaFromWidget(widget);

	if (widget == NULL || event == NULL)
		return FALSE;

	// Compute amount and direction to scroll (even tho on win32 there is
	// intensity of scrolling info in the native message, gtk doesn't
	// support this so we simulate similarly adaptive scrolling)
	int cLineScroll;
	int timeDelta = 1000000;
	GTimeVal curTime;
	g_get_current_time(&curTime);
	if (curTime.tv_sec == sciThis->lastWheelMouseTime.tv_sec)
		timeDelta = curTime.tv_usec - sciThis->lastWheelMouseTime.tv_usec;
	else if (curTime.tv_sec == sciThis->lastWheelMouseTime.tv_sec + 1)
		timeDelta = 1000000 + (curTime.tv_usec - sciThis->lastWheelMouseTime.tv_usec);
	if ((event->direction == sciThis->lastWheelMouseDirection) && (timeDelta < 250000)) {
		if (sciThis->wheelMouseIntensity < 12)
			sciThis->wheelMouseIntensity++;
		cLineScroll = sciThis->wheelMouseIntensity;
	} else {
		cLineScroll = sciThis->linesPerScroll;
		if (cLineScroll == 0)
			cLineScroll = 4;
		sciThis->wheelMouseIntensity = cLineScroll;
	}
	if (event->direction == GDK_SCROLL_UP) {
		cLineScroll *= -1;
	}
	g_get_current_time(&sciThis->lastWheelMouseTime);
	sciThis->lastWheelMouseDirection = event->direction;

	// Note:  Unpatched versions of win32gtk don't set the 'state' value so
	// only regular scrolling is supported there.  Also, unpatched win32gtk
	// issues spurious button 2 mouse events during wheeling, which can cause
	// problems (a patch for both was submitted by archaeopteryx.com on 13Jun2001)

	// Data zoom not supported
	if (event->state & GDK_SHIFT_MASK) {
		return FALSE;
	}

	// Text font size zoom
	if (event->state & GDK_CONTROL_MASK) {
		if (cLineScroll < 0) {
			sciThis->KeyCommand(SCI_ZOOMIN);
			return TRUE;
		} else {
			sciThis->KeyCommand(SCI_ZOOMOUT);
			return TRUE;
		}

	// Regular scrolling
	} else {
		sciThis->ScrollTo(sciThis->topLine + cLineScroll);
		return TRUE;
	}
}
#endif

gint ScintillaGTK::Motion(GtkWidget *widget, GdkEventMotion *event) {
	ScintillaGTK *sciThis = ScintillaFromWidget(widget);
	//Platform::DebugPrintf("Motion %x %d\n",sciThis,event->time);
	if (event->window != widget->window)
		return FALSE;
	int x = 0;
	int y = 0;
	GdkModifierType state;
	if (event->is_hint) {
		gdk_window_get_pointer(event->window, &x, &y, &state);
	} else {
		x = static_cast<int>(event->x);
		y = static_cast<int>(event->y);
		state = static_cast<GdkModifierType>(event->state);
	}
	//Platform::DebugPrintf("Move %x %x %d %c %d %d\n",
	//	sciThis,event->window,event->time,event->is_hint? 'h' :'.', x, y);
	Point pt(x, y);
	sciThis->ButtonMove(pt);
	return FALSE;
}

// Map the keypad keys to their equivalent functions
static int KeyTranslate(int keyIn) {
	switch (keyIn) {
	case GDK_ISO_Left_Tab:
		return SCK_TAB;
	case GDK_KP_Down:
		return SCK_DOWN;
	case GDK_KP_Up:
		return SCK_UP;
	case GDK_KP_Left:
		return SCK_LEFT;
	case GDK_KP_Right:
		return SCK_RIGHT;
	case GDK_KP_Home:
		return SCK_HOME;
	case GDK_KP_End:
		return SCK_END;
	case GDK_KP_Page_Up:
		return SCK_PRIOR;
	case GDK_KP_Page_Down:
		return SCK_NEXT;
	case GDK_KP_Delete:
		return SCK_DELETE;
	case GDK_KP_Insert:
		return SCK_INSERT;
	case GDK_KP_Enter:
		return SCK_RETURN;

	case GDK_Down:
		return SCK_DOWN;
	case GDK_Up:
		return SCK_UP;
	case GDK_Left:
		return SCK_LEFT;
	case GDK_Right:
		return SCK_RIGHT;
	case GDK_Home:
		return SCK_HOME;
	case GDK_End:
		return SCK_END;
	case GDK_Page_Up:
		return SCK_PRIOR;
	case GDK_Page_Down:
		return SCK_NEXT;
	case GDK_Delete:
		return SCK_DELETE;
	case GDK_Insert:
		return SCK_INSERT;
	case GDK_Escape:
		return SCK_ESCAPE;
	case GDK_BackSpace:
		return SCK_BACK;
	case GDK_Tab:
		return SCK_TAB;
	case GDK_Return:
		return SCK_RETURN;
	case GDK_KP_Add:
		return SCK_ADD;
	case GDK_KP_Subtract:
		return SCK_SUBTRACT;
	case GDK_KP_Divide:
		return SCK_DIVIDE;
	default:
		return keyIn;
	}
}

gint ScintillaGTK::KeyThis(GdkEventKey *event) {
	//Platform::DebugPrintf("SC-key: %d %x [%s]\n",
	//	event->keyval, event->state, (event->length > 0) ? event->string : "empty");
	bool shift = (event->state & GDK_SHIFT_MASK) != 0;
	bool ctrl = (event->state & GDK_CONTROL_MASK) != 0;
	bool alt = (event->state & GDK_MOD1_MASK) != 0;
	int key = event->keyval;
	if (ctrl && (key < 128))
		key = toupper(key);
	else if (!ctrl && (key >= GDK_KP_Multiply && key <= GDK_KP_9))
		key &= 0x7F;
	// Hack for keys over 256 and below command keys but makes Hungarian work.
	// This will have to change for Unicode
	else if (key >= 0xFE00)
		key = KeyTranslate(key);
	else if (IsUnicodeMode())
		;	// No operation
	else if ((key >= 0x100) && (key < 0x1000))
		key &= 0xff;

	bool consumed = false;
	bool added = KeyDown(key, shift, ctrl, alt, &consumed) != 0;
	if (!consumed)
		consumed = added;
	//Platform::DebugPrintf("SK-key: %d %x %x\n",event->keyval, event->state, consumed);
	if (event->keyval == 0xffffff && event->length > 0) {
		ClearSelection();
		if (pdoc->InsertString(CurrentPosition(), event->string)) {
			MovePositionTo(CurrentPosition() + event->length);
		}
	}
	return consumed;
}

gint ScintillaGTK::KeyPress(GtkWidget *widget, GdkEventKey *event) {
	ScintillaGTK *sciThis = ScintillaFromWidget(widget);
	return sciThis->KeyThis(event);
}

gint ScintillaGTK::KeyRelease(GtkWidget *, GdkEventKey * /*event*/) {
	//Platform::DebugPrintf("SC-keyrel: %d %x %3s\n",event->keyval, event->state, event->string);
	return FALSE;
}

void ScintillaGTK::Destroy(GtkObject* object) {
	ScintillaObject *scio = reinterpret_cast<ScintillaObject *>(object);
	// This avoids a double destruction
	if (!scio->pscin)
		return;
	ScintillaGTK *sciThis = reinterpret_cast<ScintillaGTK *>(scio->pscin);
	//Platform::DebugPrintf("Destroying %x %x\n", sciThis, object);
	sciThis->Finalise();

	if (GTK_OBJECT_CLASS (parent_class)->destroy)
		(* GTK_OBJECT_CLASS (parent_class)->destroy) (object);

	delete sciThis;
	scio->pscin = 0;
}

static void DrawChild(GtkWidget *widget, GdkRectangle *area) {
	GdkRectangle areaIntersect;
	if (widget &&
	        GTK_WIDGET_DRAWABLE(widget) &&
	        gtk_widget_intersect(widget, area, &areaIntersect)) {
		gtk_widget_draw(widget, &areaIntersect);
	}
}

void ScintillaGTK::Draw(GtkWidget *widget, GdkRectangle *area) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -