Resize `xterm.js` height to fit contents automatically - xtermjs

I'd like to use an xterm.js session that perfectly fits the height of the current contents. So every time a line is added, the size would adjust to fit that new height. The height would never be bigger than it needs to be but a scrollbar would never be shown.
I can't figure out a way to either use the fit plugin to accomplish this or to check the contents of the current xterm.js session to manually resize the row count as needed.

Beside what I wrote in the comment above, you might get away with a simpler solution by doing the following schematically (untested):
const MAX_ROWS = 20; // test upfront, as it depends on font metrics etc.
let visibleRows = 1; // start with one visible row
const term = new Terminal({
// setting scrollback is important to not lose data early
scrollback: MAX_ROWS - visibleRows,
rows: visibleRows,
...
});
// when data comes in, use the write callback to adjust terminal height
term.write(data, () => {
// get current buffer length (visible rows + rows in scrollback)
const bufferLength = term.buffer.active.length;
if (bufferLength > visibleRows) {
// resize will pull scrollback lines back into visible area
// since we have MAX_ROWS in place, bufferLength will never
// exceed your supported area (everything else is discarded)
term.resize(some_cols, bufferLength);
visibleRows = bufferLength;
// adjust scrollback to stay within (MAX_ROWS - visibleRows) constraint
// drops to 0 once we hit MAX_ROWS
term.options.scrollback = MAX_ROWS - bufferLength;
// finally adjust your container height
adjustContainerHeight();
}
});
function adjustContainerHeight() {
// can be implemented by reversing FitAddon.proposeDimensions
// maybe easier: test upfront and do a rows -> px_height mapping
...
}
Downside of this simpler approach - it might give you ugly resizing artifacts during incoming data, esp. the terminal height might jump in between and show a scrollbar for a short amount of time. If thats a showstopper for you - the double terminal approach should avoid the in between jumps and scrollback flickering.
Furthermore both ways rely on term.resize, which might trigger cmdline apps on a real PTY to resend data. This cannot be avoided, the terminal interface is meant to work that way (the application decides that on its own).
Maybe this helps.

Related

Custom Video File how much would I extract the images?

I alot of people would recommend that why not go with Bink or use DirectShow in order to play a video or even ffmpeg. However, what are movies anyways - just images put all together with sound.
I've already created a program where I take a bunch of images and place them into the customize video file. The cool thing about this - is that I can easily place it on a quad. The issue I'm having is I can only extract one image from the custom video file. When I have more than one; I have problems, which I fully understand.
I have a index lookup table of all the images sizes then the raw images. The calculation I was following was:
offset = NumberOfImages + 1 * sizeof(long).
So, with the one image - if you'll perform the offset of finding the first image would be quite easy. During the for loop it always starts with 0 and and reaches the number of images which is 1. So, it would translate like this:
offset = 1 + 1 * 4 = 8.
So, now I know the offset just for one image which is great. However, a video is with a bunch of images all together. So, I've been thinking to myself...If there was a way to reach up to a certain point then stuff the read data inside a vector.
currentPosition = 0; //-- Set the current position to zero before looping through images in file.
for (UINT i = 0; i < elements; i++) {
long tblSz = (elements + 1) * sizeof(long); // elements + 1 * 4
long off = tblSz + currentPosition; // -- Now let's calculate the offset position inside the file knowing the table size.
// in.seekg(off, std::ios_base::end); //-- Not used.
long videoSz = sicVideoIndexTable[i]; //-- Let's retreive the image size from the index table that's stored inside the file before we process each image.
// in.seekg(0, std::ios_base::beg); //-- Not used.
dataBuf.resize(videoSz); //-- Let's resize the data Buffer vector to fit the image size.
in.seekg(off, std::ios_base::beg); //-- Let's go to the calculated offset position to retrieve the image data.
std::streamsize currpos = in.gcount(); //-- Prototype not used.
in.read(&dataBuf[0], videoSz); //-- Let's read in the data according to the image size.
sVideoDesc.dataPtr = (void*)&dataBuf[0]; //-- Pass what we've read into the temporary structor before pushing it inside a vector to store the collection of images.
sVideoDesc.fileSize = videoSz;
sicVideoArray.push_back(sVideoDesc);
dataBuf.empty(); //-- Now can empty the data vector so it can be reused.
currentPosition = videoSz; //-- Set the current position to the video size so it can recalculate the offset for the next image.
}
I believe the problem lies within the seekg and in.read but that's just my gut telling me that. As you see the current position always changes.
Buttom line question is if I can load one image then why won't I be able to load multiple images from the custom video file? I'm not sure if I'm using seekg or should I just get every character until a certain point them dump the content inside a data buffer vector. I thought reading the block of data would be the answer - but I'm becoming very unsure.
I think I finally understand what your code does. You really should use more descriptive variable names. Or at least add an explanation of what each variable means. Anyway...
I believe your problem is in this line:
currentPosition = videoSz;
When it should be
currentPosition += videoSz;
You basically don't advance through your file.
Also, if you just read the images in sequentially, you might want to change your file format so that instead of a table of image sizes at the beginning, you store each image size directly followed by the image data. That way you don't need to do any of the offset calculations or seeking.

Shifting Chart without losing points

I want to shift a chart in another way than addPoint does. You can see what I mean in my JSFIDDLE: http://jsfiddle.net/Charissima/TEEdw/3/
When the chart has filled the container and the next point is added, it shifts to the left without losing the first point.
It works fine, but sometimes I can see the chart swapping a little bit. And even worth: when running over a longer time the chart gets lost. It still works, you can see it shifting and updating y in the upper right corner, but the chart is not visible any more. Even the navigator is empty.
So my question is: Is there a better and smarter way to shift the chart this way?
data.push([ xTime, prevY ]);
data.push([ xTime, y ]);
series.setData(data, true);
var faktor = ( (chart.xAxis[0].max - chart.xAxis[0].min) / 60 / 1000 ) * 200;
chart.xAxis[0].setExtremes( chart.xAxis[0].min + faktor, chart.xAxis[0].max + faktor);
I've been working on a chart with very similar attributes and have run into similar problems. One of the undesired effects of the addPoint() shift flag is that it tries to keep the data set the same size it was initialized with. I'm guessing that is your reason for not using it. It doesn't allow you to grow your data set to a certain size and then start shifting. I had this issue with the shift so I resorted to doing exactly what you are doing. I think this is the generally accepted alternative to addPoint().
But... couple that with the idea that Highchart (or maybe just Highstock) appears to have a max number of data points it will handle. I don't know if it is the same for all charts (or even for all users/browsers) but for me yours seems to disappear when the data count is 1000. See this fiddle: > jsfiddle.net/TEEdw/4/ you can watch the data length grow to 1000 and then the chart disappears. I was running into the same issue on my chart. My solution was more complicated due to other factors in my chart. But a simple solution is to monitor the data count and when it approaches 1000, switch to the addPoint() with shift method. See this fiddle: > jsfiddle.net/TEEdw/5/ There is probably other ways to allow the data set to grow and then shift at a certain point. But this one just used your existing code. You could probably dynamically set the shift flag based on data length and only set it true once the data reaches a certain length.
EDIT: Ok... there is also a plotOptions setting called turboThreshold (http://api.highcharts.com/highcharts#plotOptions.series.turboThreshold) that can be disabled. It defaults to 1000 (so that makes sense). Setting it to zero allowed your chart to keep going after 1000. See this fiddle: jsfiddle.net/TEEdw/6/

Any advantage of using 'self.view.frame.size.height', over storing it in a variable instead?

Suppose, an app has a view controller with a plethora of views inside, whose frames are relative to the view controller's frame.
Is there any advantage/disadvantage of using self.view.frame.size.height/width, over storing their values in variables, and using them instead ?? Advantages/disadvantages in terms of memory usage, CPU usage, time-delay, et cetera.
And, in the core of it, are these values of height, width, or related parameters stored in memory somewhere, or are they fetched/calculated every time the code requests them ??
I'll suggest storing the value in a variable and using that will be better.
If you call self.view.frame.size.height it will be calculated each time. They'll affect the performance.
doing:
int counter = self.view.frame.size.width;
for(int loop=0;loop<counter;loop++)
{
}
is better than:
for(int loop=0;loop<self.view.frame.size.width;loop++)
{
}
In certain scenarios, if the width and height is changing dynamically(animation logic), and you need to do something based on the values then using self.view.frame.size.width will be a good thing.
Advantages:
When views are resized, the width and height variable automatically gets updated with resized values. Storing local variables for width and height will make you write unncecessary code to manage the updation of both on each possible event causing the view to resize.
With your local variable a duplicate will increase in memory. Though the magnitude of memory waste is negligible, there is some extra memory used to hold your duplicate variable is always a fact.
Disadvantages:
If you refer the width and height from the view.frame.size.height itself, then you may loose the initial value.
I just want to point out that self.view.frame.size.height = 1 will not work as many expected. It is same as CGRect temp = self.view.frame; temp.size.height = 1;
So always separate setter/getter call and structure accessors in different line. i.e.
CGRect frame = self.view.frame; // use objc dot syntax to get frame
frame.size.height = 100; // use C struct accessors
self.view.frame = frame; // use dot syntax to set frame

Automatic Paging based on Content Area / Resolution - Telerik Grid

I am trying to accomplish something and I am not sure if it is completely possible.
I have a Telerik MVC Grid using ASP.NET MVC.
The default paging size for the grid is 10, however I want to be able to adjust the size the page (the number of rows) based on the size of the user's resolution. Is this possible?
Thanks,
Paul
It is definitely possible.
I created a solution that accomplishes the same thing - however you will have to tinker with it to get the proper height of your grid on it's own (excluding any menus/headers/footers etc.)
These steps should get you there:
Firstly - you will need to add an "onLoad" event to your MVC Grid:
.ClientEvents(events =>events.OnLoad("onLoad"))
Next - Create a Javascript event to handle the "onLoad" in your $(document).ready():
function onLoad(e)
{
//Bread and Butter will go here.
}
Finally - the last step will be to calculate the space that is not taken up by the grid (Firebug can be helpful) and tinker with it until your "formula" works out in most browsers:
function onLoad(e)
{
//Gets the height of the Window. ($(window).height())
//Subracts the height of any menus/headers/footers (in this case 275)
//Then divide by our "magic number" which you will need to tinker with
//to determine how the grid looks in different browsers. (in this case 28)
var height = Math.floor(($(window).height()-275)/28);
var grid = $("#YourGrid").data("tGrid");
grid.pageSize = height;
}
Formula :
$(window).height() - [Occupied Space] / [Magic Number]
[Occupied Space] - Total CSS Height of all objects above the Grid.
[Magic Number] - You will have to play with this one and try it out on
different browsers until you get the expected results.
That should automatically adjust your your number of rows based on your window height.The only tricky part is figuring out your own "formula" using the amount of occupied space and then picking a magic number to divide by.
Hope this helps!

BCB: how to get the (approximate) width of a character in a given TFont?

It's a TMemo, not that that should make any difference.
Googling suggests that I can use Canvas->TextWidth() but those are Delphi examples and BCB doesn't seem to offer this property.
I really want something analogous to memo->Font->Height for width.
I realize that not all fonts are fixed width, so a good estimate will do.
All that I need is to take the width of a TMemo in pixels and make a reasonable guess at how many characters of the current font it will hold.
Of course, if I really want to be lazy, I can just google for the average height/width ratio, since height is known. Remember, an approximation is good enough for me if it is tricky to get exact.
http://www.plainlanguagenetwork.org/type/utbo211.htm says, " A width to height ratio of 3:5 (0.6) is recommended for most applications"
Actually your google search is not entirely off. You do need access to a canvas object, or at least a handle to a DC object. In general when searching for help concerning VCL classes it often pays to search for delphi examples since these are more common.
Anyway to calculate the size of a string you could have a look at the TextExtent function, it is a function for the TCanvas class. Simply pass the character which width you want to test, and the return value will be a TSize construct. However there is also a TextWidth function, as well as a TextHeight function. You can use these as well. Actually these call the TextExtent internally.
You have to note one thing though, the functions use the current font of the TCanvas object, more specifically the font bound to the DC the canvas uses. So assign the font you wish to test with first, and then pass the character.
I have some old code that calculates the width of a string like this:
// This canvas could be the form canvas: canvas = Form1->Canvas or the
// memo canvas which will probably be what you want.
canvas->Font->Assign(fontToTest);
int textwidth = TextWidth(textToTest);
If you want more control of what to do, you can also do this using the Windows API, this is essentially what the VCL does for you, in that case the following example would look like this:
// This canvas could be the form canvas: canvas = Form1->Canvas
canvas->Font->Assign(fontToTest);
// The initial size, this is really important if we use wordwrapping. This is
// the text area of the memo control.
TRect rect = ClientRect;
// This is the font format we wish to calculate using, in this example our text
// will be left aligned, at the top of the rectangle.
fontformat = DT_LEFT | DT_TOP;
// Here we calculate the size of the text, both width and height are calculated
// and stored in the rect variable. Also note that we add the DT_CALCRECT to the
// fontformat variable, this makes DrawTextEx calculate the size of the text,
// without drawing it.
::DrawTextEx(canvas->handle,
textToTest.c_str(),
textToTest.Length(),
&rect,
fontformat | DT_CALCRECT,
NULL);
// The width is:
int width = rect.Width();
The fontformat is a parameter that specifies different options for how to align and layout the text, if you plan on drawing text it will be a good idea to check out the different possibilities it offers: DrawTextEx Function [1]
EDIT: Reading through your question again, it struck me that the function you might be searching for is: GetTextExtentExPoint Windows API documentation states the following about this function:
The GetTextExtentExPoint function
retrieves the number of characters in
a specified string that will fit
within a specified space and fills an
array with the text extent for each of
those characters. (A text extent is
the distance between the beginning of
the space and a character that will
fit in the space.) This information is
useful for word-wrapping calculations.
You can find more information about the GetTextExtentExPoint function here: GetTextExtentExPoint Function [2]
[1] http://msdn.microsoft.com/en-us/library/dd162499%28VS.85%29.aspx
[2] http://msdn.microsoft.com/en-us/library/dd144935%28VS.85%29.aspx
What you could do, if you have access to Win32 API functions, is create a RichEdit Window the same size as your TMemo window, place the text in the RichEdit window, send the EM_FORMATRANGE message to the window and from the result determine how many characters it will hold. Of course this method will work with multiple lines etc...

Resources