By trying to use IUP matrix I find it's usage very intuitive and it work surprisingly fast even on weak computer. So I see that I can get from that control most of I need. But, since IUP has very original way of setting properties I can't get that matrix behaves like common multicolumn list or MS listview.
This is how I format it:
Ihandle *create_mat(void)
{
mat = IupMatrix(NULL);
IupSetAttribute(mat, "READONLY", "YES");
IupSetAttribute(mat, "HIDEFOCUS", "YES");
IupSetAttribute(mat, "FRAMECOLOR", "220 220 220");
IupSetAttribute(mat, "NUMCOL", "5");
IupSetAttribute(mat, "NUMCOL_VISIBLE", "5");
IupSetAttribute(mat, "NUMLIN", "30");
IupSetAttribute(mat, "NUMLIN_VISIBLE", "30");
IupSetAttribute(mat, "RESIZEMATRIX", "YES");
IupSetAttribute(mat, "MARKMODE", "LIN");
IupSetAttribute(mat, "MARKAREA", "CONTINUOUS");
IupSetAttribute(mat, "MULTIPLE", "NO");
IupSetAttribute(mat, "BORDER", "NO");
IupSetAttribute(mat, "CURSOR", "ARROW");
IupSetAttribute(mat, "ALIGNMENT", "ARIGHT");
IupSetAttribute(mat, "ALIGNMENT1", "ALEFT");
IupSetAttribute(mat, "ALIGNMENT5", "ACENTER");
//
IupSetAttribute(mat, "WIDTH0", "30");
IupSetAttribute(mat, "WIDTH1", "150");
IupSetAttribute(mat, "WIDTH2", "50");
IupSetAttribute(mat, "WIDTH3", "50");
IupSetAttribute(mat, "WIDTH4", "50");
//
IupSetAttribute(mat, "0:0", "Row H");
IupSetAttribute(mat, "0:1", "Col1");
IupSetAttribute(mat, "0:2", "Col2");
IupSetAttribute(mat, "0:3", "Col3");
IupSetAttribute(mat, "0:4", "Col4");
IupSetAttribute(mat, "0:5", "Col5");
//
IupSetCallback(mat, "CLICK_CB", (Icallback)click);
IupSetCallback(mat, "LEAVEITEM_CB", (Icallback)leave);
IupSetCallback(mat, "ENTERITEM_CB", (Icallback)enter);
IupSetCallback(mat, "WHEEL_CB", (Icallback)wheel);
return mat;
}
All properties and events with callbacks work as expected.
Since I have a bit specific way of using/managing data it is needed that when click to any cell full row becames selected or when I change position by keyboard also.
I would also like to be able to select full row with code like it selects by clicking to row header.
Besides a click (which I catch as expected), how to check doubleclick on matrix?
And finally, not most important but it will be good to know if here exists a way to get selected line in system color (mostly blue) instead of gray?
How to easiest achieve that functionality?
(Windows7/64)
The simplest form to select the row the way you want is to use the ENTERITEM_CB callback:
static int enteritem_cb(Ihandle *ih, int lin, int col)
{
IupSetAttribute(ih,"MARKED", NULL); /* clear all marks */
IupMatSetAttribute(ih,"MARK", lin, 0, "Yes");
IupSetfAttribute(ih,"REDRAW", "L%d", lin);
return IUP_DEFAULT;
}
There is currently no way to change the selected line color. Actually because it is not a specific color. The marked cells are drawn with an attenuation at the foreground and background colors.
Related
In a Quartz application, I am trying to freeze the mouse pointer on the screen but continue to register mouse mouvements from the user. I have found how to freeze the pointer:
CGAssociateMouseAndMouseCursorPosition(false);
I am following the documentation but don't know how to get and read events that contain mouse delta (change in X and Y) data.
I found the solution. I am now getting the mouse movements like this:
CGEventMask eventMask = CGEventMaskBit(kCGEventMouseMoved);
CFMachPortRef tap = CGEventTapCreate( kCGAnnotatedSessionEventTap,
kCGHeadInsertEventTap,
kCGEventTapOptionListenOnly,
eventMask,
eventOccurred,
NULL);
CFRunLoopSourceRef rl = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, tap, 0);
CFRunLoopAddSource(CFRunLoopGetMain(), rl, kCFRunLoopCommonModes);
CGEventTapEnable(tap, true);
where the callback is:
CGEventRef eventOccurred(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void* refcon) {
if (type == kCGEventMouseMoved) {
d_x = CGEventGetIntegerValueField(event, kCGMouseEventDeltaX);
d_y = CGEventGetIntegerValueField(event, kCGMouseEventDeltaY);
}
return event;
}
Note: d_xand d_y are globally defined int that store the mouse movement between each event.
I'm using Eureka for new iOS App. I found how to set the locale of date picker which is in inline row. But I don't know it is the best way.
I tried this:
DateInlineRow() {
$0.title = "Birthday"
$0.onExpandInlineRow{ (cell, row, pickerRow) in
pickerRow.cell.datePicker.locale = Locale(identifier: "ja_JP")
}
}
it works. But this code overwrites default onExpandInlineRow's callback, so the tintColor is not work.
workaround:
DateInlineRow() {
$0.title = "Birthday"
var defaultTextColor: UIColor? = nil
$0.onExpandInlineRow{ (cell, row, pickerRow) in
pickerRow.cell.datePicker.locale = Locale(identifier: "ja_JP")
defaultTextColor = cell.detailTextLabel?.textColor
cell.detailTextLabel?.textColor = .mint
}
$0.onCollapseInlineRow{ (cell, row, pickerRow) in
cell.detailTextLabel?.textColor = defaultTextColor
}
}
I'd like to change only the locale without setting tintColor. But I have to set tintColor.
I've been reading the source code for these examples and I continue to see this option, however, I can't locate anywhere whether this is a supported feature. Do you simply get antialias by turning on this flag? Any more details on this feature?
Do you simply get antialias by turning on this flag?
No, it's only a request, not a requirement
From the spec:
5.2.1 Context creation parameters
...
antialias
If the value is true and the implementation supports antialiasing the drawing buffer will perform antialiasing using its choice of technique (multisample/supersample) and quality. If the value is false or the implementation does not support antialiasing, no antialiasing is performed.
And this
2.2 The Drawing Buffer
...
The depth, stencil and antialias attributes, when set to true, are requests, not requirements. The WebGL implementation should make a best effort to honor them. When any of these attributes is set to false, however, the WebGL implementation must not provide the associated functionality.
By setting it to false you're telling the browser "Don't turn on antialiasing" period. For example if you're making a pixelated game you might want to tell the browser to not antialias.
By NOT setting the flag the browser will generally try to use antialiasing. By setting the flag to true the browser might take it as a hint but it's still up to the browser whether antialiasing happens or not and how it happens (what settings or techniques it uses etc...). There are often bugs related to anti-aliasing and so browsers are often forced to not support it for certain GPUs. A browser might also refuse based on performance. For example when not setting the flag the browser might decide not to use antialiasing to favor performance on a smartphone and then setting the flag it might take that as a hint that the app prefers antialiasing over performance but it's still up to the browser to decide.
Here's a test
test("webgl");
test("webgl2");
function test(webglVersion) {
antialiasTest(webglVersion, {}, "default");
antialiasTest(webglVersion, {antialias: true}, "true");
antialiasTest(webglVersion, {antialias: false}, "false");
}
function antialiasTest(webglVersion, options, desc) {
const canvas = document.createElement("canvas");
canvas.width = 2;
canvas.height = 2;
const gl = canvas.getContext(webglVersion, options);
if (!gl) {
log(webglVersion, 'not supported');
return;
}
const vs = `
attribute vec4 position;
void main() {
gl_Position = position;
}
`;
const fs = `
void main() {
gl_FragColor = vec4(1, 0, 0, 1);
}
`;
const programInfo = twgl.createProgramInfo(gl, [vs, fs]);
const bufferInfo = twgl.createBufferInfoFromArrays(gl, {
position: {
numComponents: 2,
data: [
-1, -1,
1, -1,
-1, 1,
],
},
});
gl.useProgram(programInfo.program);
twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo);
gl.drawArrays(gl.TRIANGLES, 0, 3);
const pixels = new Uint8Array(2 * 2 * 4);
gl.readPixels(0, 0, 2, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
const isNotAntialiased =
isRedOrBlack(pixels[ 0]) &&
isRedOrBlack(pixels[ 4]) &&
isRedOrBlack(pixels[ 8]) &&
isRedOrBlack(pixels[12]) ;
log(webglVersion, 'with antialias =', desc, 'was', isNotAntialiased ? 'NOT' : '', 'antialiased');
}
function isRedOrBlack(r) {
return r === 255 || r === 0;
}
function log(...args) {
const elem = document.createElement("div");
elem.textContent = [...args].join(' ');
document.body.appendChild(elem);
}
<script src="https://twgljs.org/dist/4.x/twgl.min.js"></script>
Tangentially related though, WebGL2 allows you to create antialiased renderbuffers with renderbufferStorageMultisample and resolve them using blitFramebuffer, a feature which was not available in WebGL1. Rendering to an antialiased framebuffer and then blitting that to the canvas is a way to force antialiasing, at least in WebGL2.
For all details regarding WebGL, start with the specification. From section 5.2 you can see the available attributes, with antialias defaulting to true:
dictionary WebGLContextAttributes {
GLboolean alpha = true;
GLboolean depth = true;
GLboolean stencil = false;
GLboolean antialias = true;
GLboolean premultipliedAlpha = true;
GLboolean preserveDrawingBuffer = false;
WebGLPowerPreference powerPreference = "default";
GLboolean failIfMajorPerformanceCaveat = false;
};
I strongly recommend also setting alpha to false as this will improve overall performance on certain systems.
I'm trying to use overFont and overColor on TextButton so the button appearance can changes when the mouse move over.
Here's the style I defined.
var buttonStyle = new TextButtonStyle();
buttonStyle.fontColor = new Color(1f, 1f, 1f, 1f);
buttonStyle.disabledFontColor = new Color(0, 0, 0, 0.4f);
buttonStyle.down = skin.getDrawable( "button_down");
buttonStyle.up= skin.getDrawable( "button_up");
buttonStyle.over= skin.getDrawable( "button_over");
buttonStyle.overFontColor = new Color(0, 0.3f, 0.3f, 1f);
buttonStyle.font = font
skin.add("default", buttonStyle);
The button is created as follows:
var startGameButton = new TextButton("Start game", skin);
startGameButton.x = buttonX;
startGameButton.y = currentY;
startGameButton.width = BUTTON_WIDTH;
startGameButton.height = BUTTON_HEIGHT;
stage.addActor(startGameButton);
/*startGameButton.addListener ([ Event e |
Gdx.app.log ("App", "Start game") ;
return true ;
])*/
startGameButton.addListener (new ChangeListener () {
override changed(ChangeEvent event, Actor actor) {
Gdx.app.log ("App", "Start game") ;
}
})
While the down and up state are properly taken into account, the over properties are not used: the button doesn't change when the mouse enters the button area.
buttonStyle.fontOverColor = Color.BLUE; works fine for me,
try to pass to your TextButton constructor not skin, but buttonStyle,
in TextButton there is such constructor
public TextButton (String text, TextButtonStyle style)
It's difficult to say something else, because code not looks like real working code, I mean var keyword or this code is not correct (there is no public variables x, y, width, height):
startGameButton.x = buttonX;
startGameButton.y = currentY;
startGameButton.width = BUTTON_WIDTH;
startGameButton.height = BUTTON_HEIGHT;
If changing constructor will not help you, please post your real code.
I have basic confusion in understanding of IUP events system.
Now I am talking about matrix.
This is how it is created:
Ihandle *create_mat(void)
{
mat = IupMatrix(NULL);
IupSetAttribute(mat, "READONLY", "YES");
IupSetCallback(mat, "CLICK_CB", (Icallback)click);
IupSetCallback(mat, "BUTTON_CB", (Icallback)button);
return mat;
}
Here are callbacks:
int click(Ihandle *mat, int lin, int col)
{
char* value = IupMatGetAttribute(mat, "", lin, col);
if (!value) value = "NULL";
printf("click_cb(%d, %d)\n", lin, col);
return IUP_DEFAULT;
}
int button(Ihandle *mat, int button, int pressed, int x, int y, char* status)
{
printf("button %d, %d, %d, %d %s\n", button, pressed, x, y, status);
return IUP_DEFAULT;
}
Problem is in that I need both callbacks active but in showed situation CLICK event isn't fired.
If I disable BUTTON_CB then CLICK event is fired. But I need both, for click, left button doubleclick, right button release etc...
Is this normal behavior that BUTTON_CB excludes CLICK_CB or I do something wrong?
Actually, how would I get "lin" and "col" from inside BUTTON_CB or WHEEL_CB handler of matrix if CLICK_CB, ENTERITEM_CB and LEAVEITEM_CB which gives lin and col is not available (not fired in described situation)?
And more, how would I get "active control" (name, type of control with focus) from event handlers used on form's level?
Is this normal behavior that BUTTON_CB excludes CLICK_CB or I do something wrong?
Yes, it is. Because the BUTTON_CB is a IupCanvas callback and CLICK_CB is a IupMatrix callback. Remeber that IupMatrix inherits from IupCanvas. So internally IupMatrix is using the BUTTON_CB callback to implement several features.
So in this case what you have to do is to save the previous callback before assigning a new one, and call the old one from inside your own. Something like this:
old_callback = IupGetCallback(mat, "BUTTON_CB");
IupSetCallback(mat, "BUTTON_CB", new_callback);
int new_callback(...)
{
return old_callback(...)
}
Actually, how would I get "lin" and "col" from inside BUTTON_CB or WHEEL_CB handler of matrix if CLICK_CB, ENTERITEM_CB and LEAVEITEM_CB which gives lin and col is not available (not fired in described situation)?
Use the function pos = IupConvertXYToPos(mat, x, y) where pos=lin*numcol + col. To compute lin and col is quite simple considering they are integer values.
And more, how would I get "active control" (name, type of control with focus) from event handlers used on form's level?
I don't fully undestood your question. But I think that IupGetFocus and IupGetClassName could be the functions you want.
I will answer to my own question by using Antonio's advices so other people interesting for IUP can have benefit from those posts.
If I understand well, what is not likely, here is how I make BUTTON_CB handler for my matrix:
int button(Ihandle *mat, int button, int pressed, int x, int y, char* status)
{
//actually 'name' is Ihandle
//and class name is a 'type'
//in compare with other toolkits
char* name = IupGetClassName(mat);
//so since we have handle already
//we can't be here if we are not in concrete matrix
//and this comparision is not needed
if (strncmp(name, "matrix", sizeof(name)) == 0)
{
//if left mouse button is down
if (button == IUP_BUTTON1 && pressed == 1)
{
//my calculation is not 100% correct
//but good enough for this sample
int pos = IupConvertXYToPos(mat, x, y);
_line = pos/numcol;
_col = pos%numcol;
//if is doubleclick
if (status[5] == 'D')
{
//press ENTER key
//and open another modal dialog
//with argument 'sel'
k_any(mat, K_CR);
printf("Doubleclick\n");
//say HANDLED for IUP
//but not matter when READONLY is "YES"
return IUP_IGNORE;
}
//calculate (public) sel
//for select a clicked line
sel = _line + from - 1;
refreshl(from, sel);
printf("Click\n");
return IUP_IGNORE;
}
}
return IUP_DEFAULT;
}
This work's as expected.
Please further suggestion if something is not OK.