GeUserArea Manual

About

GeUserArea is the base class for all gadgets that can be displayed in a GeDialog. A new gadget is created by implementing a subclass of GeUserArea. Such a gadget manages user interaction and draws the gadget interface in the GUI.

Note
GeUserArea based classes can only be used with a GeDialog or GeDialog based classes. To create a custom GUI element that can be used in the Attribute Manager one must implement a CustomGuiData / iCustomGui based plugin.

Allocation

An instance of a GeUserArea based class is typically stored as a member of the parent GeDialog. It is added to the dialog layout using:

  • GeDialog::AddUserArea(): Adds a user area to the dialog layout.
  • GeDialog::AttachUserArea(): Connects the user area gadget with the actual user area instance.

See GeDialog Manual.

// This example adds the given user area "userarea" to the GeDialog layout.
private:
MyUserArea _geUserArea;
public:
Bool CreateLayout()
{
SetTitle("GeUserArea Dialog"_s);
C4DGadget* const userAreaGadget = this->AddUserArea(100, BFH_LEFT, 400, 100);
if (userAreaGadget)
this->AttachUserArea(_geUserArea, userAreaGadget);
maxon::Bool Bool
Definition: ge_sys_math.h:46
@ BFH_LEFT
Aligned to the left. 1<<3.
Definition: gui.h:312

The parent dialog is accessible with:

  • GeUserArea::GetDialog(): Returns the parent GeDialog.

GeUserArea Based Classes

A custom user area is created by implementing a subclass of GeUserArea. This subclass can implement different virtual functions that define the behaviour of the gadget.

The user area is initiated with:

  • GeUserArea::Init(): Called once when the user area is initialized.
  • GeUserArea::InitValues(): Initiates the values displayed with the user area.
// This example initializes the GeUserArea and sets the timer.
Bool Init()
{
this->SetTimer(500); // value in ms
return true;
}

The size of the user area is handled with:

  • GeUserArea::GetMinSize(): Defines the minimum size of the user area.
  • GeUserArea::Sized(): Called when the user area is resized.
// This example defines the minimum size of this GeUserArea.
Bool GetMinSize(Int32& w, Int32& h)
{
w = 400;
h = 100;
return true;
}
// This example stores the width and height after the GeUserArea was resized.
void Sized(Int32 w, Int32 h)
{
_width = w;
_height = h;
}
maxon::Int32 Int32
Definition: ge_sys_math.h:51

Different messages are sent to a user area:

// This example catches a message to set the cursor when the mouse is over the user area.
Int32 Message(const BaseContainer& msg, BaseContainer& result)
{
// messages are identified by the BaseContainer ID
switch (msg.GetId())
{
{
result.SetString(RESULT_BUBBLEHELP, "This is an example GeUserArea"_s);
return true;
}
}
return GeUserArea::Message(msg, result);
}
PyObject PyObject * result
Definition: abstract.h:43
@ BFM_GETCURSORINFO
Definition: gui.h:561
@ RESULT_BUBBLEHELP
String Bubble help text.
Definition: gui.h:565
@ RESULT_CURSOR
Int32 Mouse cursor: MOUSE
Definition: gui.h:564
static const Int32 MOUSE_POINT_HAND
Point hand cursor.
Definition: ge_prepass.h:2733
const char const char * msg
Definition: object.h:438

The primary purpose of a user area is to draw the actual user interface:

  • GeUserArea::DrawMsg(): Called to draw the user area.
// This example draws a white rectangle in the given region.
void DrawMsg(Int32 x1, Int32 y1, Int32 x2, Int32 y2, const BaseContainer& msg)
{
OffScreenOn();
SetClippingRegion(x1, y1, x2, y2);
DrawSetPen(Vector(1, 1, 1));
DrawRectangle(x1, y1, x2, y2);
}
maxon::Vec3< maxon::Float64, 1 > Vector
Definition: ge_math.h:140
Note
To optimize the drawing call skip the redraw if only the focus has changed, see ::BFM_DRAW_REASON in Draw.

A user area can catch user interaction events:

  • GeUserArea::InputEvent(): Called when an input event (keyboard, mouse) is received.
// This example checks if the input device is the mouse.
// If so, the mouse coordinates are transferred into local coordinates.
Bool InputEvent(const BaseContainer& msg)
{
// check the input device
switch (msg.GetInt32(BFM_INPUT_DEVICE))
{
// some mouse interaction
{
// get the cursor position
Int32 mx = msg.GetInt32(BFM_INPUT_X);
Int32 my = msg.GetInt32(BFM_INPUT_Y);
Global2Local(&mx, &my);
ApplicationOutput("Mouse Event at " + String::IntToString(mx) + " - " + String::IntToString(my));
return true;
}
}
return false;
}
@ BFM_INPUT_MOUSE
Mouse.
Definition: gui.h:711
@ BFM_INPUT_Y
Float Y value.
Definition: gui.h:729
@ BFM_INPUT_DEVICE
Int32 Device:
Definition: gui.h:710
@ BFM_INPUT_X
Float X value.
Definition: gui.h:728
#define ApplicationOutput(formatString,...)
Definition: debugdiagnostics.h:204

See also GeDialog Gadget Interaction.

Read-Only Properties

These properties can be read from a user area:

  • GeUserArea::GetId(): Returns the ID of the user area.
  • GeUserArea::GetWidth(): Returns the width of the user area.
  • GeUserArea::GetHeight(): Returns the height of the user area.
  • GeUserArea::IsEnabled(): Returns true if the user area is enabled.
  • GeUserArea::IsR2L(): Returns true if the user area should be drawn in right-to-left layout mode (Arabic interface).
  • GeUserArea::HasFocus(): Returns true if the user area has the focus.
// This example sends the BFM_ACTION message from a GeUserArea to the parent GUI element.
// This message can be caught in GeDialog::Message() or GeDialog::Command().
BaseContainer action(BFM_ACTION);
action.SetInt32(BFM_ACTION_ID, GetId());
SendParentMessage(action);
@ BFM_ACTION_ID
Int32 ID of the dialog element that triggered the action.
Definition: gui.h:747
@ BFM_ACTION
One of the child elements made any action:
Definition: gui.h:746
// This example changes the color of the user area depending on the focus.
void DrawMsg(Int32 x1, Int32 y1, Int32 x2, Int32 y2, const BaseContainer& msg)
{
OffScreenOn();
SetClippingRegion(x1, y1, x2, y2);
// check if the user area has the focus
if (this->HasFocus())
DrawSetPen(Vector(0.0, 0.0, 1.0));
else
DrawSetPen(Vector(0.0, 0.2, 0.8));
DrawRectangle(x1, y1, x2, y2);
}

Timer

A user area can use an internal timer that calls GeUserArea::Timer() periodically.

  • GeUserArea::SetTimer(): Initializes the timer clock.
// This example initializes the GeUserArea and sets the timer.
Bool Init()
{
this->SetTimer(500); // value in ms
return true;
}
// This example implements GeUserArea::Timer().
// The function is called in the interval defined with GeUserArea::SetTimer().
void Timer(const BaseContainer& msg)
{
ApplicationOutput("Timer tick");
}

User Interaction

A user area can handle user interaction events by implementing GeUserArea::InputEvent(). The following functions are used to get more detailed information on the current event:

  • GeUserArea::GetInputState(): Gets the current state of the given input device.
  • GeUserArea::GetInputEvent(): Gets the next input event for the given device from the event queue.
  • GeUserArea::KillEvents(): Flushes all events from the window message queue.
  • GeUserArea::IsHotkeyDown(): Returns true if the given hotkey is pressed. see HOTKEYFLAGS.

A special operation is a mouse drag event inside the user area. Such a mouse drag is initiated in reaction to certain user interaction using these functions:

  • GeUserArea::MouseDragStart(): Starts the mouse drag operation.
  • GeUserArea::MouseDrag(): Polls the mouse during a drag.
  • GeUserArea::MouseDragEnd(): Ends a mouse drag operation.
// This example handles a mouse drag event of the left mouse button.
const Int32 device = msg.GetInt32(BFM_INPUT_DEVICE);
const Int32 channel = msg.GetInt32(BFM_INPUT_CHANNEL);
// check if this is a mouse event triggered by the left mouse button
if (device == BFM_INPUT_MOUSE && channel == BFM_INPUT_MOUSELEFT)
{
BaseContainer channels;
BaseContainer state;
Int32 startX = msg.GetInt32(BFM_INPUT_X);
Int32 startY = msg.GetInt32(BFM_INPUT_Y);
Float deltaX = 0.0f;
Float deltaY = 0.0f;
Global2Local(&startX, &startY);
// start mouse drag
MouseDragStart(BFM_INPUT_MOUSELEFT, (Float)startX, (Float)startY, MOUSEDRAGFLAGS::DONTHIDEMOUSE);
// handle mouse drag
while (MouseDrag(&deltaX, &deltaY, &channels) == MOUSEDRAGRESULT::CONTINUE)
{
// get state of the left mouse button
break;
// check if the mouse button is not pressed
if (state.GetInt32(BFM_INPUT_VALUE) == 0)
break;
// print something if the mouse has moved
if (deltaX != 0.0 || deltaY != 0.0)
ApplicationOutput("Mouse Drag");
}
MouseDragEnd();
return true;
}
PyArena _PyASTOptimizeState * state
Definition: compile.h:99
CONTINUE
Drag still in progress.
Definition: ge_prepass.h:2
DONTHIDEMOUSE
Show mouse pointer during drag.
Definition: ge_prepass.h:1
@ BFM_INPUT_MOUSELEFT
Left mouse button.
Definition: gui.h:716
@ BFM_INPUT_VALUE
Int32 Value of the input channel (true/false or a Int32 value, e.g. for scroll wheel data).
Definition: gui.h:726
@ BFM_INPUT_CHANNEL
Int32 Contains the key or mouse button. See also KEY.
Definition: gui.h:715
Bool GetInputState(Int32 askdevice, Int32 askchannel, BaseContainer &res)
maxon::Float Float
Definition: ge_sys_math.h:57
Definition: grammar.h:37

Drag and Drop

The user can drag and drop various elements onto a user area. The user area is informed about this event through messages sent to GeUserArea::Message(). These functions are used to react to those messages:

  • GeUserArea::CheckDropArea(): Returns true if the drag event is over the user area.
  • GeUserArea::GetDragPosition(): Gets the coordinates of the drag event.
  • GeUserArea::GetDragObject(): Gets the object that is dragged.
  • GeUserArea::SetDragDestination(): Sets the cursor that should be displayed. See MOUSE.

See also Drag and Drop.

// This example handles a drag and drop event in GeUserArea::Message().
{
// check drag area
if (!CheckDropArea(msg, true, true))
break;
void* data = nullptr;
// get the drag data
if (!GetDragObject(msg, &type, &data))
return false;
// check if an C4DAtom was dragged
return false;
// get content
const AtomArray* const elements = static_cast<AtomArray*>(data);
// check content
if (!elements->GetIndex(0))
return false;
// check if drag has finished
if (msg.GetInt32(BFM_DRAG_FINISHED))
{
// loop through all elements of the AtomArray
for (Int32 i = 0; i < elements->GetCount(); ++i)
{
const C4DAtom* const atom = elements->GetIndex(i);
// check if the given C4DAtom is a BaseList2D element
if (atom && atom->IsInstanceOf(Tbaselist2d))
{
const BaseList2D* const baselistObject = static_cast<const BaseObject*>(atom);
ApplicationOutput("Dragged object: " + baselistObject->GetName());
}
}
}
else
{
// if in drag, show different mouse cursor
return SetDragDestination(MOUSE_POINT_HAND);
}
return true;
}
Py_ssize_t i
Definition: abstract.h:645
#define atom
Definition: graminit.h:72
@ BFM_DRAG_FINISHED
Bool Drag finished.
Definition: gui.h:797
@ DRAGTYPE_ATOMARRAY
AtomArray.
Definition: gui.h:786
@ BFM_DRAGRECEIVE
Drag receive. (See DragAndDrop.)
Definition: gui.h:774
#define Tbaselist2d
2D list.
Definition: ge_prepass.h:995
PyObject ** type
Definition: pycore_pyerrors.h:34

It is also possible to start a drag and drop operation from a user area. This is typically done in reaction to some user interaction.

  • GeUserArea::HandleMouseDrag(): Starts a drag and drop operation.
// This example starts a drag and drop operation.
Bool InputEvent(const BaseContainer& msg)
{
const Int32 device = msg.GetInt32(BFM_INPUT_DEVICE);
const Int32 channel = msg.GetInt32(BFM_INPUT_CHANNEL);
if (device == BFM_INPUT_MOUSE)
{
if (channel == BFM_INPUT_MOUSELEFT)
{
// drag a color
Vector red(1.0, 0.0, 0.0);
// start a drag & drop event of dragging a color value
if (HandleMouseDrag(msg, DRAGTYPE_RGB, &red, 0))
return true;
}
}
return false;
}
@ DRAGTYPE_RGB
RGB color.
Definition: gui.h:788

Parent Message

A user area can send messages to its parent GeDialog. This is typically done to inform the dialog that some user interaction occurred and that the managed values changed.

  • GeUserArea::SendParentMessage(): Sends a message to the parent dialog.

See GUI and Interaction Messages Manual.

// This example sends the BFM_ACTION message from a GeUserArea to the parent GUI element.
// This message can be caught in GeDialog::Message() or GeDialog::Command().
BaseContainer action(BFM_ACTION);
action.SetInt32(BFM_ACTION_ID, GetId());
SendParentMessage(action);

Drawing

Drawing Basics

The central task of a user area is to draw something to Cinema 4D's user interface. The drawing operations have to happen inside the GeUserArea::DrawMsg() function.

The drawing operation can be triggered with:

  • GeUserArea::Redraw(): Forces the user area to redraw itself.
  • GeUserArea::LayoutChanged(): Informs Cinema 4D that the user area has new dimensions. This will result in a redraw.

Drawing Operations

The following functions can be used to draw inside the canvas provided by the user area. For more advanced drawing operations one can use a GeClipMap and GeUserArea::DrawBitmap().

The color and opacity settings are handled with:

  • GeUserArea::GetColorRGB(): Gets the color value for the given color ID. See c4d_colors.h.
  • GeUserArea::DrawSetPen(): Sets the currently used drawing color.
  • GeUserArea::DrawSetOpacity(): Sets the opacity used in the following drawing operations.
// This example draws a white background and a black text.
// draw a white background
DrawSetPen(Vector(1.0f));
DrawRectangle(x1, y1, x2, y2);
// draw some text
DrawSetTextCol(Vector(0.0f), Vector(1.0f));
DrawText("Hello World!"_s, 0, 0, DRAWTEXT_HALIGN_LEFT);
#define DRAWTEXT_HALIGN_LEFT
Align to the left.
Definition: c4d_gui.h:189

Different styles used with various drawing functions are (::LINESTYLE):

  • LINESTYLE::NORMAL
  • LINESTYLE::DOTTED
  • LINESTYLE::DASHED
  • LINESTYLE::DASHED_INV

These functions draw primitive shapes:

  • GeUserArea::DrawLine(): Draws a line.
  • GeUserArea::DrawRectangle(): Draws a rectangle.
  • GeUserArea::DrawFrame(): Draws a frame.
  • GeUserArea::DrawBezierLine(): Draws a Bezier line.
  • GeUserArea::DrawBezierFill(): Draws a Bezier line and fills the area.
  • GeUserArea::DrawPolyLine(): Draws a poly line.
  • GeUserArea::DrawPolyFill(): Draws a poly line and fills the area.
  • GeUserArea::DrawEllipseLine(): Draws an ellipse.
  • GeUserArea::DrawEllipseFill(): Draws an ellipse and fills the area.
// This example draws shapes in a GeUserArea.
// draw base
{
const maxon::Vector2d center(300, 60);
const maxon::Vector2d radius(40, 40);
DrawSetPen(Vector(1, 1, 0));
DrawEllipseFill(center, radius);
DrawSetPen(Vector(0, 0, 0));
DrawEllipseLine(center, radius);
}
// draw eyes
DrawSetPen(Vector(0, 0, 0));
{
const maxon::Vector2d center(285, 50);
const maxon::Vector2d radius(3, 3);
DrawEllipseFill(center, radius);
}
{
const maxon::Vector2d center(315, 50);
const maxon::Vector2d radius(3, 3);
DrawEllipseFill(center, radius);
}
// draw mouth
{
BezierPoint p;
p.c1 = Vector2d(280, 90);
p.c2 = Vector2d(320, 90);
p.p = Vector2d(320, 70);
DrawBezierLine(Vector2d(280, 70), maxon::ToSingletonBlock(p), false, 1.0, LINESTYLE::NORMAL);
}
unsigned char * p
Definition: floatobject.h:87
#define MAXON_SCOPE
Definition: apibase.h:2891
Block< T > ToSingletonBlock(T &value)
Definition: block.h:984
NORMAL
Definition: lib_birender.h:2
maxon::Vec2< maxon::Float64, 1 > Vector2d
Definition: ge_math.h:142

A BaseBitmap can both be drawn to the canvas and filled with the current pen:

  • GeUserArea::DrawBitmap(): Draws a BaseBitmap. For effects see BMP.
  • GeUserArea::FillBitmapBackground(): Fills the given BaseBitmap with the current pen color.

See also BaseBitmap Manual.

// This example fills a GeClipMap and draws the resulting BaseBitmap in the user area.
AutoAlloc<GeClipMap> clipMap;
if (clipMap)
{
// get monospaced font
BaseContainer font;
GeClipMap::GetDefaultFont(GE_FONT_DEFAULT_MONOSPACED, &font);
clipMap->Init(200, 50, 32);
clipMap->BeginDraw();
// fill background
clipMap->SetColor(255, 255, 255, 255);
clipMap->FillRect(0, 0, 200, 50);
// draw text
clipMap->SetFont(&font, 20.0);
clipMap->SetColor(0, 0, 0, 255);
clipMap->TextAt(0, clipMap->GetTextHeight(), "This is some text.");
clipMap->EndDraw();
// get bitmap
BaseBitmap* const bitmap = clipMap->GetBitmap();
if (bitmap)
{
// draw bitmap
const Int32 width = bitmap->GetBw();
const Int32 height = bitmap->GetBh();
DrawBitmap(bitmap, 0, 0, width, height, 0, 0, width, height, BMP_NORMAL);
}
}
@ BMP_NORMAL
Standard scaling by the operating system. Fast but low quality when using uneven scaling factors.
Definition: gui.h:171
@ GE_FONT_DEFAULT_MONOSPACED
The Cinema 4D monospaced font.
Definition: lib_clipmap.h:121
unsigned long Py_ssize_t width
Definition: pycore_traceback.h:88

The border style of the user area is defined with:

  • GeUserArea::DrawBorder(): Draws a border with the given style, see BORDER.
  • GeUserArea::GetBorderSize(): Gets the space required to draw a border. Typically used with GeUserArea::GetMinSize().
// This example draws a round border for the GeUserArea.
DrawBorder(BORDER_ROUND, 0, 0, GetWidth(), GetHeight());
@ BORDER_ROUND
Border with round corners.
Definition: gui.h:271

Text is drawn with these functions:

  • GeUserArea::DrawText(): Draws the given String.
  • GeUserArea::DrawSetTextCol(): Sets the text foreground and background color.
  • GeUserArea::DrawSetFont(): Sets the text font, see FONT.
  • GeUserArea::DrawGetTextWidth(): Returns the width in pixels of the given String.
  • GeUserArea::DrawGetFontHeight(): Returns the height in pixels of the given String.
  • GeUserArea::DrawGetTextWidth_ListNodeName(): Returns the width in pixels of the name of the given BaseList2D.
  • GeUserArea::DrawGetFontBaseLine(): Returns the base line of the current font.
  • GeUserArea::DrawSetTextRotation(): Sets the text rotation.
// This example draws some text and a line under that text.
const String text { "Hello World!" };
const Int32 left = 100;
// draw text
DrawSetTextCol(Vector(0.0f), Vector(1.0f));
DrawSetFont(FONT_MONOSPACED);
DrawText(text, left, 0, DRAWTEXT_HALIGN_LEFT);
// draw a line
const Int32 baseline = DrawGetFontBaseLine() + 1;
const Int32 length = DrawGetTextWidth(text);
DrawSetPen(Vector(0.5f));
DrawLine(left, baseline, left + length, baseline);
@ FONT_MONOSPACED
Monospaced font.
Definition: gui.h:25
PyWideStringList Py_ssize_t length
Definition: initconfig.h:448
PyObject * text
Definition: pycore_traceback.h:70

A user area can support a dynamic fading effect that is typically used to change the background color of the gadget after the cursor moved over it:

  • GeUserArea::ActivateFading(): Activates the dynamic fading. The message ::BFM_FADE will be sent to the user area.
  • GeUserArea::AdjustColor(): Calculates the new color while fading.

See also Fading.

// This example shows a GeUserArea that is "fading".
// When the cursor is over the user area the fading is activated.
// Cinema 4D will then send the message BFM_FADE to the user area so
// it can interpolate a color and use this color to redraw itself.
class FadingUserArea : public GeUserArea
{
public:
FadingUserArea() { };
~FadingUserArea() { };
Int32 Message(const BaseContainer& msg, BaseContainer& result)
{
// messages are identified by the BaseContainer ID
switch (msg.GetId())
{
{
// cursor is over the user area
// start fading
ActivateFading(100);
return true;
}
case BFM_FADE:
{
// receive fade message and update the COLOR_BG used in DrawMsg()
const Float percentage = msg.GetFloat(BFM_FADE);
AdjustColor(COLOR_BG, COLOR_BG_HIGHLIGHT, percentage);
// redraw using the updated COLOR_BG
Redraw();
return true;
}
}
return GeUserArea::Message(msg, result);
}
void DrawMsg(Int32 x1, Int32 y1, Int32 x2, Int32 y2, const BaseContainer& msg)
{
OffScreenOn();
SetClippingRegion(x1, y1, x2, y2);
// draw background with COLOR_BG
DrawSetPen(COLOR_BG);
DrawRectangle(x1, y1, x2, y2);
// draw text
DrawSetTextCol(COLOR_CONSOLE_TEXT, COLOR_TRANS);
DrawSetFont(FONT_MONOSPACED);
DrawText("User Area"_s, 0, 0, DRAWTEXT_HALIGN_LEFT);
}
};
@ COLOR_BG_HIGHLIGHT
Definition: c4d_colors.h:329
@ COLOR_TRANS
Definition: c4d_colors.h:14
@ COLOR_CONSOLE_TEXT
Definition: c4d_colors.h:94
@ COLOR_BG
Definition: c4d_colors.h:16
@ BFM_FADE
Definition: gui.h:1009

It is also possible to be informed when the cursor leaves the user area:

  • RemoveLastCursorInfo(): Registers a callback function that is called when the cursor leaves the user area. The function typically sends the message ::BFM_CURSORINFO_REMOVE back to the user area.
// This example user area registers a callback function with RemoveLastCursorInfo().
// This function is called when the cursor leaves the user area. It is used to send the
// message BFM_CURSORINFO_REMOVE back to the user area to inform it about the event.
// declarations
static void RemoveCursorInfo();
class RemoveCursorUserArea;
static RemoveCursorUserArea* g_userArea = nullptr; // static variable storing pointer to a user area
// user area will display a different color depending if the cursor is over the area or not
class RemoveCursorUserArea : public GeUserArea
{
public:
RemoveCursorUserArea()
{
if (g_userArea == this)
g_userArea = nullptr;
};
~RemoveCursorUserArea() { };
Int32 Message(const BaseContainer& msg, BaseContainer& result)
{
// messages are identified by the BaseContainer ID
switch (msg.GetId())
{
{
// register RemoveCursorInfo() callback
g_userArea = this;
RemoveLastCursorInfo(RemoveCursorInfo);
_cursorInside = true;
Redraw();
return true;
}
{
// message "BFM_CURSORINFO_REMOVE" sent by RemoveCursorInfo()
_cursorInside = false;
Redraw();
break;
}
}
return GeUserArea::Message(msg, result);
}
void DrawMsg(Int32 x1, Int32 y1, Int32 x2, Int32 y2, const BaseContainer& msg)
{
OffScreenOn();
SetClippingRegion(x1, y1, x2, y2);
// gadget color is controlled by the cursor position
if (_cursorInside)
DrawSetPen(Vector(1.0, 0.0, 0.0));
else
DrawSetPen(Vector(0.0, 1.0, 0.0));
DrawRectangle(x1, y1, x2, y2);
}
private:
Bool _cursorInside = false; // set to true if the cursor is over the user area
};
// function will be called by the user area when the cursor left its area
static void RemoveCursorInfo()
{
if (g_userArea == nullptr)
return;
// send message to the user area
BaseContainer bc;
g_userArea->Message(BaseContainer(BFM_CURSORINFO_REMOVE), bc);
}
@ BFM_CURSORINFO_REMOVE
Sent when mouse cursor has left a user area.
Definition: gui.h:577
Bool RemoveLastCursorInfo(LASTCURSORINFOFUNC func)

Clipping

Clipping is used to limit drawing operations to certain areas:

  • GeUserArea::SetClippingRegion(): Specifies the clipping region for the drawing functions.
  • GeUserArea::ClearClippingRegion(): Clears the clipping region set with GeUserArea::SetClippingRegion().
  • GeUserArea::OffScreenOn(): Enables double buffering to avoid blinking and flickering effects. Automatically sets the clipping area to the whole user area or the given region.
// This example draws a white rectangle in the given region.
void DrawMsg(Int32 x1, Int32 y1, Int32 x2, Int32 y2, const BaseContainer& msg)
{
OffScreenOn();
SetClippingRegion(x1, y1, x2, y2);
DrawSetPen(Vector(1, 1, 1));
DrawRectangle(x1, y1, x2, y2);
}

Miscellaneous

Miscellaneous functions are:

  • GeUserArea::ScrollArea(): Scrolls the user area.
  • GeUserArea::GetPixelRatio(): Returns the screen pixel ratio to indicate Retina displays.

Coordinate Transformation

These functions are used to transform coordinates into different spaces:

  • GeUserArea::Local2Global(): Transforms local coordinates to global window coordinates.
  • GeUserArea::Global2Local(): Transforms global window coordinates to local coordinates.
  • GeUserArea::Local2Screen(): Transforms local coordinates to screen coordinates.
  • GeUserArea::Screen2Local(): Transforms screen coordinates to local coordinates.
// This example creates a pop up menu when the right mouse button was pressed.
Bool InputEvent(const BaseContainer& msg)
{
const Int32 device = msg.GetInt32(BFM_INPUT_DEVICE);
const Int32 channel = msg.GetInt32(BFM_INPUT_CHANNEL);
// check if this is a mouse event triggered by the left mouse button
if (device == BFM_INPUT_MOUSE && channel == BFM_INPUT_MOUSERIGHT)
{
// get the cursor position
Int32 x = msg.GetInt32(BFM_INPUT_X);
Int32 y = msg.GetInt32(BFM_INPUT_Y);
Global2Local(&x, &y);
Local2Screen(&x, &y);
// define pop up menu
BaseContainer bc;
bc.InsData(5159, "CMD"); // cube
bc.InsData(0, String());
bc.InsData(5160, "CMD"); // sphere
// show pop up menu
ShowPopupMenu(GetDialog()->Get(), x, y, bc);
return true;
}
return false;
}
PyObject * x
Definition: bytesobject.h:38
@ BFM_INPUT_MOUSERIGHT
Right mouse button.
Definition: gui.h:717
Int32 ShowPopupMenu(CDialog *cd, Int32 screenx, Int32 screeny, const BaseContainer &bc, Int32 flags=POPUP_RIGHT|POPUP_EXECUTECOMMANDS|POPUP_ALLOW_FILTERING, Int32 *res_mainid=nullptr)
const Class< R > & Get(const Id &cls)
Definition: objectbase.h:2090

Further Reading