wxGrid shows large empty border on right - wxwidgets

By default, wxGrid shows a small ( 10 pixels? ) blank border on the right hand side, after the last column. Calling SetMargins() has no effect on it.
It is irritating, but I can live with it.
However, if I set the the row label width to zero then the blank border grows much larger. If I have just one column, the effect is horrible. It looks like wxGrid is leaving room for the non-existent label.
myPatGrid = new wxGrid(panel,IDC_PatGrid,wxPoint(10,10),wxSize(150,300) );
myPatGrid->SetRowLabelSize(0);
myPatGrid->CreateGrid(200,1);
myPatGrid->SetColLabelValue(0,L"Patient IDs");
Is there a way to remove this border?
Note that if I set the size of the wxgrid window to narrower in the wxGrid constructor, hoping to hide the border, I now get a horizontal scroll bar which is horrible too.
myPatGrid = new wxGrid(panel,IDC_PatGrid,wxPoint(10,10),wxSize(100,300) );
myPatGrid->SetRowLabelSize(0);
myPatGrid->CreateGrid(200,1);
myPatGrid->SetColLabelValue(0,L"Patient IDs");
Gives me
I just upgraded to wxWidgets v2.8.12 - problem still exists.

I didn't find an "autosize" function to fit columns in the grid space.
As a workaround, if you have only one column set its width to
myPatGrid->SetColMinimalWidth(0, grid_width - wxSYS_VSCROLL_X - 10)
otherwise, sum other column's width and adapt the last one to fit the remaining space (minus scrollbar width, minus 10).
EDIT: I have a working example, which produces this:
int gridSize = 150;
int minSize = gridSize - wxSYS_VSCROLL_X - 2; // scrollbar appear if higher
grid->SetRowLabelSize(0);
grid->SetColMinimalWidth(0, minSize);
grid->SetColSize(0, minSize); // needed, otherwise column will not resize
grid->ForceRefresh();
grid->SetColLabelValue(0, "COORD");
EDIT2: I succeded to remove the remaining margin with this:
int gridSize = 150;
int minSize = gridSize - 16; // trial & error
grid->SetMargins(0 - wxSYS_VSCROLL_X, 0);

Solving something similar yesterday I would like to contribute with following what does the job for me. Perhaps this is going to help someone else:
void RecalculateGridSize(wxGrid *grid, int cols) {
if (grid == NULL)
return;
grid->AutoSizeColumns();
float cumulative = 0, param = 0;
for (int i = 0; i < cols; ++i)
cumulative += grid->GetColSize(i);
//not stretching when client size lower then calculated
if(grid->GetClientSize().x < cumulative)
return;
param = (float) grid->GetClientSize().x / cumulative;
for (int i = 0; i < cols; ++i) {
if (i != cols - 1)
grid->SetColSize(i, int(grid->GetColSize(i)*param) - 2); //-2 for each line per column
else
grid->SetColSize(i, int(grid->GetColSize(i)*param)); //leaving last column full to fill properly
}
}
Note: This is doing particularly well when linked with OnSize() event.

Related

Directx11 heightmap texture real-time modification problem

I'm making a terrain tool.
I made a 2D texture and am using it as a height map.
I want to change a specific part of the heightmap, but I'm having a problem.
I changed certain small parts, but the whole landscape of the texture is changed.
I would like to know the cause of this problem and how to solve it
thank you.
`HeightMap ShaderResourceView Create Code
void TerrainRenderer::BuildHeightmapSRV(ID3D11Device* device)
{
ReleaseCOM(mHeightMapSRV);
ReleaseCOM(m_hmapTex);
D3D11_TEXTURE2D_DESC texDesc;
texDesc.Width = m_terrainData.HeightmapWidth; //basic value 2049
texDesc.Height = m_terrainData.HeightmapHeight; //basic value 2049
texDesc.MipLevels = 1;
texDesc.ArraySize = 1;
texDesc.Format = DXGI_FORMAT_R16_FLOAT;
texDesc.SampleDesc.Count = 1;
texDesc.SampleDesc.Quality = 0;
texDesc.Usage = D3D11_USAGE_DYNAMIC;
texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
texDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
texDesc.MiscFlags = 0;
// HALF is defined in xnamath.h, for storing 16-bit float.
std::vector<HALF> hmap(mHeightmap.size());
//current mHeightmap is all zero.
std::transform(mHeightmap.begin(), mHeightmap.end(), hmap.begin(), XMConvertFloatToHalf);
D3D11_SUBRESOURCE_DATA data;
data.pSysMem = &hmap[0];
data.SysMemPitch = m_terrainData.HeightmapWidth * sizeof(HALF);
data.SysMemSlicePitch = 0;
HR(device->CreateTexture2D(&texDesc, &data, &m_hmapTex));
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
srvDesc.Format = texDesc.Format;
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
srvDesc.Texture2D.MostDetailedMip = 0;
srvDesc.Texture2D.MipLevels = -1;
HR(device->CreateShaderResourceView(m_hmapTex, &srvDesc, &mHeightMapSRV));
}
`HeightMap Texture modifying code
D3D11_MAPPED_SUBRESOURCE mappedData;
//m_hmapTex is ID3D11Texture2D*
HR(m_texMgr.m_context->Map(m_hmapTex, D3D11CalcSubresource(0, 0, 1), D3D11_MAP_WRITE_DISCARD, 0, &mappedData));
HALF* heightMapData = reinterpret_cast<HALF*>(mappedData.pData);
D3D11_TEXTURE2D_DESC heightmapDesc;
m_hmapTex->GetDesc(&heightmapDesc);
UINT width = heightmapDesc.Width;
for (int row = 0; row < width/4; ++row)
{
for (int col = 0; col < width/4; ++col)
{
idx = (row * width) + col;
heightMapData[idx] = static_cast<HALF>(XMConvertFloatToHalf(200));
}
}
m_texMgr.m_context->Unmap(m_hmapTex, D3D11CalcSubresource(0,0,1));
Please refer to the picture below
The lower right area renders the HeightMap texture.
I wanted to edit only 1/4 width and height, but that's all changed.
enter image description here
When the completed heightmap is applied, it works normally.
enter image description here
A texture does not always have the same width and height in memory as the definition suggests. Some textures strides (lines) are oversized. You have to use the Stride Size * Row to calculate the offset to write into.

How to overlap a buffer in Objective-C

I'm trying to do FFT on the iPhone, and I realised that I had not overlapped my input prior to windowing. I was wondering if anyone could give me some insight on to how to properly overlap my input buffer.
I am wanting to overlap bufferSamples by a factor of 4, and I understand that it is to be done using memove functions, but I can't figure out how to get it to work in regard to overlapping.
enum
{
frameSize = 2048,
overlap = 4,
range = 8192,
step = frameSize/overlap,
};
static COMPLEX_SPLIT A;
// For each sample in buffer...
for (int j = 0; j < audioBufferList.mNumberBuffers; j++)
{
// Declaring samples from audio buffer list
SInt16 *bufferSamples = (SInt16*)audioBufferList.mBuffers[j].mData;
// Overlapping here?
////////////////////////
//// vDSP FUNCTIONS ////
////////////////////////
// Creating Hann window function
for (int i = 0; i < frameSize; i++)
{
double window = 0.5 * (1.0 - cos((2.0 * M_PI * i) / (frameSize - 1)));
// Applying window to each sample
A.realp[i] = window * bufferSamples[i];
A.imagp[i] = 0;
}
// Further DSP...
To get an overlap factor of 4, you need to save the last 75% of the data that, before windowing, was input to the previous FFT. Then use that saved data as the first 75% of the current FFT, with only the last 25% from current or not yet used data. memmove can be used to copy data to and from the temporary save data buffers. Repeat as necessary to use up the data available.

Getting minimum number of MKMapRects from a MKPolygon

So I have a function that takes two MKMapRect's and the second intersects with the first one. So the function creates an MKPolygon that is the first rect without the intersecting parts:
-(void) polygons:(MKMapRect)fullRect exclude:(MKMapRect)excludeArea{
NSLog(#"Y is: %f height: %f",excludeArea.origin.y,excludeArea.size.height);
double top = excludeArea.origin.y - fullRect.origin.y;
double lft = excludeArea.origin.x - fullRect.origin.x;
double btm = (fullRect.origin.y + fullRect.size.height) - (excludeArea.origin.y + excludeArea.size.height);
double rgt = (fullRect.origin.x + fullRect.size.width) - (excludeArea.origin.x + excludeArea.size.width);
double ot = fullRect.origin.y, it = (ot + top);
double ol = fullRect.origin.x, il = (ol + lft);
double ob = (fullRect.origin.y + fullRect.size.height), ib = (ob - btm);
double or = (fullRect.origin.x + fullRect.size.width), ir = (or - rgt);
MKMapPoint points[11] = {{ol,it}, {ol,ot}, {or,ot}, {or,ob}, {ol,ob}, {ol,it}, {il,it}, {ir,it}, {ir,ib}, {il,ib}, {il,it}};
MKPolygon *polygon = [MKPolygon polygonWithPoints:points count:11];
}
And my question is now how do I get the minimum number of MKMapRects from this MKPolygon? I have done some googling as well as looking through the forum but havn't found anything.
EDIT:
So the goal is the following:
I have a MKMapRect rect1, then I have a list of rectangles, rectList, which is MKMapRects intersecting with rect1 and what I want to do is create a rectilinear MKPolygon of rect1, remove the surface of all MKMapRects in rectList from rect1 and then create the minimum number of MKMaprects from the created rectilinear MKPolygon.
Right now the problem is the following: I am able to create a polygon when removing one MKMapRect from rect1 but I dont know how to remove the following maprects from rect1 and I dont know how to extract the minimum set of MkMapRects from the polygon created.
Best regards
Peep
I'm not sure if this is what you're looking for or if I understand the question fully, but if all you need to know is the minimum number of rectangles in a polygon that's created by subtracting one rectangle from another you should be able to do it by checking the number of corner points in the second rectangle that are contained in the first rectangle. In pseudo code:
int minNumRects(MKRect r1, MKRect r2) {
int numPointsContained = 0;
for (Point p in r2) {
if (MKMapRectContainsPoint(r1, p)) {
numPointsContained++;
}
}
if (numPointsContained == 1) {
return 2;
} else if (numPointsContained == 2) {
return 3;
} else if (numPointsContained == 4) {
return 4;
} else {
return 0;
}
}
P.S. - This assumes that the rectangles are axis-aligned but as far as I know that's the case with MKRects

Looping moving background objective-C

I am testing a background-loop animation where there will be to images both 1024x768 pixels in dimension, move leftwards, go offscreen, then jump back to the other side, and repeat.
I was able to do this by creating a constant speed for both background image to move (successful), and then I tried the following code to make it jump, but there was a problem:
if((background.center.x) < -511){
background.center = CGPointMake(1536, background.center.y);
}
if((background2.center.x) < -511){
background2.center = CGPointMake(1536, background2.center.y);
}
Somehow this is not working the way I expected. It leaves a few pixels of gap every time, and I am confused why. Does anyone know what's causing this to happen and how to fix it? Thanks!
It seems like you have forgotten to take into account the distance moved. The greater than expression might have been triggered because you moved to far. I guess your movement is larger than 1 pixel/frame.
I am not sure what kind of values that are feeding your movement but I think to take into account the movement you should do something like...
if ((background.center.x) < -511){
CGFloat dist = background.center.x + 512;
background.center = CGPointMake(1536+dist, background.center.y);
}
if ((background2.center.x) < -511){
CGFloat dist = background2.center.x + 512;
background2.center = CGPointMake(1536+dist, background2.center.y);
}
Rather than have the two images move (sort of) independently, I would keep track of a single backgroundPosition variable and then constantly update the position of both images relative to that one position. This should keep everything nice and tidy:
CGFloat const backgroundWidth = 1024;
CGFloat const backgroundSpeed = 2;
- (void)animateBackground {
backgroundPosition -= backgroundSpeed;
if (backgroundPosition < 0) {
backgroundPosition += backgroundWidth;
}
background1.center.x = backgroundPosition - backgroundWidth/2;
background2.center.x = backgroundPosition + backgroundWidth/2;
}

Timing function for "Wheel of Fortune" style ticker

I'm trying to create a function that changes a label's text. I want it in a "Wheel of Fortune" style where the text changes really quickly at first but slows down over time, then stops at the final text. I have the text as strings in an array.
I'm guessing I would need an exponential function to do this but maths is not my strong point. Currently I'm trying:
- (void)timer {
float time = 0.5;
float increase = 0.05;
for(int x = 0; x < 100; x++) {
sleep(time);
time = time + increase;
NSLog(#"%f", time); //Log to show time of each iteration
}
}
I don't need help linking it up with labels etc., I just need help to get the timing right.