Ncurses menu - remembering selection - c

I am using Ncurses library to do some interactive menus, and I don't know how to do one thing. I have simple menu with few options, I turned of O_ONEVALUE so many options can be selected at the same time, before posting menu I get all the menu items and mark them as selected or not, depending on a bit mask that I keep stored somewhere else, but when the menu is posted every option is turned off, here is the code:
//acquiring menu items
ITEM** header_items = menu_items(params.header_opts_menu);
ITEM* cur_item;
if (header_items == NULL)
{
client_cleanup();
syslog_nsys_f(LOG_ERR, "error while getting header menu items");
}
//selecting appropriate items
long header_menu_items_count = ARRAY_SIZE(header_menu_choices);
for (i = 0; i < header_menu_items_count; ++i)
{
if ((params.header_flags & (1 << (i))) != 0)
decision = TRUE;
else
decision = FALSE;
if (set_item_value(header_items[i], TRUE) != E_OK)
{
client_cleanup();
syslog_nsys_f(LOG_ERR,"error while setting menu item value");
}
}
if (post_menu(params.header_opts_menu) != E_OK)
{
client_cleanup();
syslog_nsys_f(LOG_ERR,"error while posting header options menu");
}
set_menu_items(params.header_opts_menu,header_items);
refresh();
even if I set value of every item to TRUE nothing happens, where is my mistake?

It looks like you are attempting to call set_menu_items after calling post_menu. Check the return value from set_menu_items you are probably getting an E_POSTED error.

Related

GTK: "key-press-event" handling while Shift is pressed

I'm writing a small program: it's a lone drop-down menu with lowercase letters as menuitem labels:
If you hold Shift, the labels become capitalized (I wrote a "key-press-event" and "key-release-event" handler for this). The problem is that while Shift is pressed, I still want to navigate the menu and choose items with Enter press. The default handlers aren't get triggered if some modifier is pressed, so I handle it in the following way:
static gboolean menu_key_event(GtkWidget *menu, GdkEvent *event, gpointer data) {
(void)data;
GdkEventKey *key_event = (GdkEventKey*)event;
switch (key_event->keyval) {
case GDK_KEY_Shift_L:
case GDK_KEY_Shift_R: ;
bool b = (key_event->type == GDK_KEY_PRESS) ? true : false;
gtk_container_foreach(GTK_CONTAINER(menu), menuitem_capitalize_label, &b);
return TRUE;
break;
case GDK_KEY_Return:
if ((key_event->type == GDK_KEY_PRESS) &&
(key_event->state & GDK_SHIFT_MASK)) {
// I want default callback to handle this
g_signal_emit_by_name(menu, "activate-current");
return TRUE;
}
break;
case GDK_KEY_Up:
case GDK_KEY_Down:
if ((key_event->type == GDK_KEY_PRESS) &&
(key_event->state & GDK_SHIFT_MASK)) {
// Some function I wrote to fiddle with menu items,
// simulating default selection behavior
menu_rotate_selection(GTK_MENU_SHELL(menu), key_event->keyval);
return TRUE;
}
break;
}
return FALSE;
}
Could this be done in a more elegant fashion? In short, I want my application handle Enter, arrow keys and Shift+Enter, Shift+ arrow keys the same way without needing to manually process it.
I've finally found needed signal to select menuitems ("move-current"), so my own menu_rotate_selection function is no longer needed. That signal name is confusing though, I'd rather think its purpose to actually move the menuitem itself whithin the menu (first I thought the other obscure-named signal "cycle-focus" is for changing selection). Now it can be rewriten as following:
...
case GDK_KEY_Up:
case GDK_KEY_Down:
if ((key_event->type == GDK_KEY_PRESS) &&
(key_event->state & GDK_SHIFT_MASK)) {
GtkMenuDirectionType dir = (key_event->keyval == GDK_KEY_Up) ?
GTK_MENU_DIR_PREV : GTK_MENU_DIR_NEXT;
g_signal_emit_by_name(menu, "move-current", dir);
return TRUE;
}
break;
...
This pretty much answers my question.

Issue reading / writing a dynamic BYTE array to the registry [duplicate]

This question already has an answer here:
How to get size of dynamic array in C++ [duplicate]
(1 answer)
Closed 6 years ago.
I have this method that initializes a buffer:
void CCreateReportDlg::InitAutoAssignStates()
{
int iNumColumns = m_Grid.GetColumnCount();
ASSERT(m_pbyAutoAssignStates == NULL);
if (m_pbyAutoAssignStates == NULL)
{
m_pbyAutoAssignStates = new BYTE[iNumColumns];
if (m_pbyAutoAssignStates != NULL)
{
// This sets them all to AUTO_ASSIGN_INCLUDE
ZeroMemory(m_pbyAutoAssignStates, iNumColumns * sizeof(BYTE));
// DATE is never used for auto assign
m_pbyAutoAssignStates[COLUMN_DATE] = AUTO_ASSIGN_NOT_USED;
}
}
}
So far, so good. This buffer gets passed into a dialog class.
// Receives pointer to a BYTE* array.
// This is owned by the parent.
void CAutoAssignSettingsDlg::SetAutoAssignStates(BYTE *pbyAutoAssignStates)
{
m_pbyAutoAssignStates = pbyAutoAssignStates;
}
No problems there. I then have a checked list on the dialog that is mapped to each of the states in the above buffer.
When the popup dialog is about to close it revises the buffer:
void CAutoAssignSettingsDlg::UpdateAutoAssignStates()
{
LVITEM sItem;
int iAssign, iNumAssign;
if (m_pbyAutoAssignStates != NULL)
{
sItem.mask = LVIF_IMAGE|LVIF_PARAM;
sItem.iSubItem = 0;
iNumAssign = m_listAssign.GetItemCount();
for (iAssign = 0; iAssign < iNumAssign; iAssign++)
{
sItem.iItem = iAssign;
m_listAssign.GetItem(&sItem);
if (sItem.iImage == IMG_CHECKED)
m_pbyAutoAssignStates[sItem.lParam] = AUTO_ASSIGN_EXCLUDE;
else
m_pbyAutoAssignStates[sItem.lParam] = AUTO_ASSIGN_INCLUDE;
}
}
}
This all works. But then I want to save it to the registry. At the moment I do it like this:
theApp.WriteProfileBinary(strSection, _T("AssignStates"), m_pbyAutoAssignStates, sizeof(m_pbyAutoAssignStates));
Finally, in the parent dialog, I adjusted the code that reads the settings in from the registry. So now, before the InitAutoAssignStates call I do this:
theApp.GetProfileBinary(strSection,_T("AssignStates"), &ppData, &uSize);
if (uSize > 0)
{
m_pbyAutoAssignStates = new BYTE[uSize];
memcpy(m_pbyAutoAssignStates, ppData, uSize);
}
// Tidy memory
if (uSize != 0)
{
delete[] ppData;
ppData = NULL;
}
The subsequent InitAutoAssignStates method is only called now if the buffer is NULL. So in theory I shoudlread back in the buffer that I saved. But it is not working. The set of items ticked in my check boxes do not match.
What am I doing wrong?
I found a related question that said you could not do what I was trying to achieve without knowing the number of elements. This did surprise me but I am not going to argue.
I adjusted my code to pass in the number of elements to the popup dialog and then I was able to save like this:
theApp.WriteProfileBinary(strSection, _T("AssignStates"),
m_pbyAutoAssignStates,
sizeof(m_pbyAutoAssignStates[0]) * m_iNumAutoAssignStateValues);
This works correctly. When I read this buffer back I get matching check boxes in my list.

Lost on how to implement writeCharecteristic in my android code

I am using android studio's example bluetoothlegatt, which has a read function and and works completely find (it interacts with the TI keyfob I have which sends over values when pressed).
However, I have no idea how to put in writeCharecteristic because my previous attempts have failed.
Can someone help me with this? I would like to send a "1" over so that the keyfob's led lights up.
Edit: I have tried something like this
public void writeCharacteristic(byte[] value) { BluetoothGattService LumService = mBluetoothGatt.getService(UUID_LUM_APP);
if (LumService == null) {
System.out.println("LumService null"); return; }
BluetoothGattCharacteristic LumChar = LumService.getCharacteristic(UUID_LUM_CHAR);
if (LumChar == null) {
System.out.println("LumChar null"); return; }
LumChar.setValue(value); boolean status = mBluetoothGatt.writeCharacteristic(LumChar);
System.out.println("Write Status: " + status);
This is not my code, though, just an example. I want to integrate this into the bluetoothlegatt given already, but I have had no success with it.

Stop angular from updating table

I am using angluar js. On my page I have a table. Each record in the table has a col that is a drop down list. When this value gets changed and the user clicks save, the page checks to see if the value in the drop down has already been used. If it has, an alert message is presented and if not, then some code is executed. My problem is when the alert/error message is displayed. When this is displayed, I don't want the table to update according to the new value but it still does. How can I prevent this? I am really new to using angular.
$scope.saveDeviceUpdate = function (updatedDevice, deviceId) {
var numDevicesForBus = 0;
for (var i = 0; i < $scope.data.deviceList.length; i++)
{
if ($scope.data.deviceList[i].BusNumber == updatedDevice.busNumber)
{
numDevicesForBus++;
}
}
if (numDevicesForBus == 0)
{
dataService.updateDevice(updatedDevice, deviceId);
}
else
{
alert("This bus already has a device!");
}
};

Display response time seems too slow on simple functions

I have written an application in C using GTK 2.0 for a touchscreen panel with an ARM processor running debian linux. It is a very basic application that presents a few buttons (event boxes) on screen that can be clicked. On one page, I have 4 fields to present a "list" that can be scrolled through by clicking an up arrow and a down arrow (also event boxes). My function (code below) for the scrolling is very basic...it just updates each field with the next item from the array. Everything works fine, but the problem I am seeing is that if you repeatedly click the scroll button a little too quickly, it jumps ahead a few list items too far. My guess as to what is happening is that, when clicking too fast, the counter advances faster than the screen can update, so that by the time you click again it is actually updating with the then too-high counter. I wouldn't be concerned if it only happened when clicking REALLY fast, but I think the slow response seems way out of line for such a simple function repeating at a reasonably quick rate.
I'm hoping maybe someone has some input on something I might be missing in regards to screen refreshes with GTK?
Thank you in advance for any thoughts or advice!
Here is my code for my "volume-up" function and "scroll-up" function, both having the same problem. There are corresponding "scroll-down" and "volume-down" functions with the same issue:
static void sr_vol_up_clicked (GtkWidget *fakewidget, GdkEvent *fakeevent, gpointer number)
{
g_timer_start(lock_timer);
gtk_image_set_from_file (GTK_IMAGE(sr_vol_up_button),"./images/Admin/navigation_up_arrow_DOWN.png");
if (sr_current_level < 100)
{
sr_current_level = sr_current_level + 1;
gtk_label_set_text (GTK_LABEL(sr_current_level_label), (g_strdup_printf("%i", sr_current_level)));
set_sr_volume(sr_current_level);
}
gtk_image_set_from_file (GTK_IMAGE(sr_vol_up_button),"./images/Admin/navigation_up_arrow_UP.png");
}
And the other:
static void scroll_show_up ()
{
g_timer_start(lock_timer);
if (show_scroll_count > 0)
{
if (show_one_displayed - 1 < 0)
{
show_one_displayed = (show_loop_list->len -1);
}
else
{
show_one_displayed = show_one_displayed - 1;
}
gtk_label_set_text (GTK_LABEL(upcoming_show_1_label), get_show_name((char *)g_ptr_array_index(show_loop_list, show_one_displayed)));
if (show_two_displayed - 1 < 0)
{
show_two_displayed = (show_loop_list->len -1);
}
else
{
show_two_displayed = show_two_displayed - 1;
}
gtk_label_set_text (GTK_LABEL(upcoming_show_2_label), get_show_name((char *)g_ptr_array_index(show_loop_list, show_two_displayed)));
if (show_three_displayed - 1 < 0)
{
show_three_displayed = (show_loop_list->len -1);
}
else
{
show_three_displayed = show_three_displayed - 1;
}
gtk_label_set_text (GTK_LABEL(upcoming_show_3_label), get_show_name((char *)g_ptr_array_index(show_loop_list, show_three_displayed)));
if (show_four_displayed - 1 < 0)
{
show_four_displayed = (show_loop_list->len -1);
}
else
{
show_four_displayed = show_four_displayed - 1;
}
gtk_label_set_text (GTK_LABEL(upcoming_show_4_label), get_show_name((char *)g_ptr_array_index(show_loop_list, show_four_displayed)));
show_scroll_count = show_scroll_count - 1;
}
}

Resources