/* help.c * * * Copyright (C) 2014 Toxic All Rights Reserved. * * This file is part of Toxic. * * Toxic is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Toxic is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Toxic. If not, see . * */ #include #include "help.h" #include "misc_tools.h" #include "toxic.h" #include "windows.h" #ifdef PYTHON #include "api.h" #endif /* PYTHON */ #ifdef PYTHON #define HELP_MENU_HEIGHT 10 #else #define HELP_MENU_HEIGHT 9 #endif /* PYTHON */ #define HELP_MENU_WIDTH 26 void help_init_menu(ToxWindow *self) { if (self->help->win) { delwin(self->help->win); } int y2, x2; getmaxyx(self->window, y2, x2); if (y2 < HELP_MENU_HEIGHT || x2 < HELP_MENU_WIDTH) { return; } self->help->win = newwin(HELP_MENU_HEIGHT, HELP_MENU_WIDTH, 3, 3); self->help->active = true; self->help->type = HELP_MENU; } static void help_exit(ToxWindow *self) { delwin(self->help->win); *(self->help) = (struct Help) { 0 }; } static void help_init_window(ToxWindow *self, int height, int width) { if (self->help->win) { delwin(self->help->win); } int y2, x2; getmaxyx(stdscr, y2, x2); if (y2 <= 0 || x2 <= 0) { return; } height = MIN(height, y2); width = MIN(width, x2); self->help->win = newwin(height, width, 0, 0); } static void help_draw_menu(ToxWindow *self) { WINDOW *win = self->help->win; wmove(win, 1, 1); wattron(win, A_BOLD | COLOR_PAIR(RED)); wprintw(win, " Help Menu\n"); wattroff(win, A_BOLD | COLOR_PAIR(RED)); wattron(win, A_BOLD | COLOR_PAIR(BLUE)); wprintw(win, " g"); wattroff(win, A_BOLD | COLOR_PAIR(BLUE)); wprintw(win, "lobal commands\n"); wattron(win, A_BOLD | COLOR_PAIR(BLUE)); wprintw(win, " c"); wattroff(win, A_BOLD | COLOR_PAIR(BLUE)); wprintw(win, "hat commands\n"); wprintw(win, " c"); wattron(win, A_BOLD | COLOR_PAIR(BLUE)); wprintw(win, "o"); wattroff(win, A_BOLD | COLOR_PAIR(BLUE)); wprintw(win, "nference commands\n"); wprintw(win, " g"); wattron(win, A_BOLD | COLOR_PAIR(BLUE)); wprintw(win, "r"); wattroff(win, A_BOLD | COLOR_PAIR(BLUE)); wprintw(win, "oupchat commands\n"); #ifdef PYTHON wattron(win, A_BOLD | COLOR_PAIR(BLUE)); wprintw(win, " p"); wattroff(win, A_BOLD | COLOR_PAIR(BLUE)); wprintw(win, "lugin commands\n"); #endif /* PYTHON */ wattron(win, A_BOLD | COLOR_PAIR(BLUE)); wprintw(win, " f"); wattroff(win, A_BOLD | COLOR_PAIR(BLUE)); wprintw(win, "riendlist controls\n"); wattron(win, A_BOLD | COLOR_PAIR(BLUE)); wprintw(win, " k"); wattroff(win, A_BOLD | COLOR_PAIR(BLUE)); wprintw(win, "ey bindings\n"); wprintw(win, " e"); wattron(win, A_BOLD | COLOR_PAIR(BLUE)); wprintw(win, "x"); wattroff(win, A_BOLD | COLOR_PAIR(BLUE)); wprintw(win, "it menu\n"); box(win, ACS_VLINE, ACS_HLINE); wnoutrefresh(win); } static void help_draw_bottom_menu(WINDOW *win) { int y2, x2; getmaxyx(win, y2, x2); UNUSED_VAR(x2); wmove(win, y2 - 2, 1); wattron(win, A_BOLD | COLOR_PAIR(BLUE)); wprintw(win, " m"); wattroff(win, A_BOLD | COLOR_PAIR(BLUE)); wprintw(win, "ain menu |"); wprintw(win, " e"); wattron(win, A_BOLD | COLOR_PAIR(BLUE)); wprintw(win, "x"); wattroff(win, A_BOLD | COLOR_PAIR(BLUE)); wprintw(win, "it"); } static void help_draw_global(ToxWindow *self) { WINDOW *win = self->help->win; wmove(win, 1, 1); wattron(win, A_BOLD | COLOR_PAIR(RED)); wprintw(win, "Global Commands:\n"); wattroff(win, A_BOLD | COLOR_PAIR(RED)); wprintw(win, " /add : Add contact with optional message\n"); wprintw(win, " /accept : Accept friend request\n"); wprintw(win, " /avatar : Set an avatar (leave path empty to unset)\n"); wprintw(win, " /conference : Create a conference where type: text | audio\n"); wprintw(win, " /connect : Manually connect to a DHT node\n"); wprintw(win, " /decline : Decline friend request\n"); wprintw(win, " /requests : List pending friend requests\n"); wprintw(win, " /status : Set status (Online, Busy, Away)\n"); wprintw(win, " /note : Set a personal note\n"); wprintw(win, " /nick : Set your nickname\n"); wprintw(win, " /nospam : Change part of your Tox ID to stop spam\n"); wprintw(win, " /log or : Enable/disable logging\n"); wprintw(win, " /myid : Print your Tox ID\n"); wprintw(win, " /group : Create a new group chat\n"); #ifdef GAMES wprintw(win, " /game : Play a game\n"); #endif /* GAMES */ #ifdef QRCODE #ifdef QRPNG wprintw(win, " /myqr or : Print your Tox ID's QR code to a file.\n"); #else wprintw(win, " /myqr : Print your Tox ID's QR code to a file.\n"); #endif /* QRPNG */ #endif /* QRCODE */ wprintw(win, " /clear : Clear window history\n"); wprintw(win, " /close : Close the current chat window\n"); wprintw(win, " /quit or /exit : Exit Toxic\n"); #ifdef AUDIO wattron(win, A_BOLD); wprintw(win, "\n Audio:\n"); wattroff(win, A_BOLD); wprintw(win, " /lsdev : List devices where type: in|out\n"); wprintw(win, " /sdev : Set active device\n"); #endif /* AUDIO */ #ifdef VIDEO wattron(win, A_BOLD); wprintw(win, "\n Video:\n"); wattroff(win, A_BOLD); wprintw(win, " /lsvdev : List video devices where type: in|out\n"); wprintw(win, " /svdev : Set active video device\n"); #endif /* VIDEO */ #ifdef PYTHON wattron(win, A_BOLD); wprintw(win, "\n Scripting:\n"); wattroff(win, A_BOLD); wprintw(win, " /run : Load and run the script at path\n"); #endif /* PYTHON */ help_draw_bottom_menu(win); box(win, ACS_VLINE, ACS_HLINE); wnoutrefresh(win); } static void help_draw_chat(ToxWindow *self) { WINDOW *win = self->help->win; wmove(win, 1, 1); wattron(win, A_BOLD | COLOR_PAIR(RED)); wprintw(win, "Chat Commands:\n"); wattroff(win, A_BOLD | COLOR_PAIR(RED)); wprintw(win, " /invite : Invite contact to a conference \n"); wprintw(win, " /join : Join a pending conference\n"); wprintw(win, " /sendfile : Send a file\n"); wprintw(win, " /savefile : Receive a file\n"); wprintw(win, " /cancel : Cancel file transfer where type: in|out\n"); #ifdef AUDIO wattron(win, A_BOLD); wprintw(win, "\n Audio:\n"); wattroff(win, A_BOLD); wprintw(win, " /call : Audio call\n"); wprintw(win, " /answer : Answer incoming call\n"); wprintw(win, " /reject : Reject incoming call\n"); wprintw(win, " /hangup : Hangup active call\n"); wprintw(win, " /sdev : Change active device\n"); wprintw(win, " /mute : Mute active device if in call\n"); wprintw(win, " /sense : VAD sensitivity threshold\n"); wprintw(win, " /bitrate : Set the audio encoding bitrate\n"); #endif /* AUDIO */ #ifdef VIDEO wattron(win, A_BOLD); wprintw(win, "\n Video:\n"); wattroff(win, A_BOLD); wprintw(win, " /res : Set video resolution\n"); wprintw(win, " /vcall : Video call\n"); wprintw(win, " /video : Toggle video in call\n"); #endif /* VIDEO */ #ifdef GAMES wprintw(win, " /game : Play a game with contact\n"); #endif /* GAMES */ help_draw_bottom_menu(win); box(win, ACS_VLINE, ACS_HLINE); wnoutrefresh(win); } static void help_draw_groupchats(ToxWindow *self) { WINDOW *win = self->help->win; wmove(win, 1, 1); wattron(win, A_BOLD | COLOR_PAIR(RED)); wprintw(win, "Groupchat commands:\n"); wattroff(win, A_BOLD | COLOR_PAIR(RED)); wprintw(win, " /chatid : Print this group's ID\n"); wprintw(win, " /close : Leave the group with an optional part message\n"); wprintw(win, " /disconnect : Disconnect from the group (credentials retained)\n"); wprintw(win, " /ignore : Ignore a peer\n"); wprintw(win, " /unignore : Unignore an ignored peer\n"); wprintw(win, " /kick : Remove a peer from the group\n"); wprintw(win, " /list : Print a list of peers currently in the group\n"); wprintw(win, " /locktopic : Set the topic lock: on | off\n"); wprintw(win, " /mod : Promote a peer to moderator\n"); wprintw(win, " /passwd : Set a password needed to join the group\n"); wprintw(win, " /peerlimit : Set the maximum number of peers that can join\n"); wprintw(win, " /privacy : Set the privacy state: private | public\n"); wprintw(win, " /rejoin : Reconnect to the groupchat\n"); wprintw(win, " /silence : Silence a peer for the entire group\n"); wprintw(win, " /unsilence : Unsilence a silenced peer\n"); wprintw(win, " /status : Set your status\n"); wprintw(win, " /topic : Set the group topic\n"); wprintw(win, " /unmod : Demote a moderator\n"); wprintw(win, " /voice : Set the voice state: all | mod | founder\n"); wprintw(win, " /whisper : Send a private message to a peer\n"); wprintw(win, " /whois : Print whois info for a peer\n"); help_draw_bottom_menu(win); box(win, ACS_VLINE, ACS_HLINE); wnoutrefresh(win); } static void help_draw_keys(ToxWindow *self) { WINDOW *win = self->help->win; wmove(win, 1, 1); wattron(win, A_BOLD | COLOR_PAIR(RED)); wprintw(win, "Key bindings:\n"); wattroff(win, A_BOLD | COLOR_PAIR(RED)); wprintw(win, " Ctrl+O and Ctrl+P : Navigate through the tabs\n"); wprintw(win, " Page Up and Page Down : Scroll window history one line\n"); wprintw(win, " Ctrl+F and Ctrl+V : Scroll window history half a page\n"); wprintw(win, " Ctrl+H : Move to the bottom of window history\n"); wprintw(win, " Ctrl+up and Ctrl+down : Scroll peer list in conference\n"); wprintw(win, " Ctrl+B : Toggle the conference peerlist\n"); wprintw(win, " Ctrl+J : Insert new line\n"); wprintw(win, " Ctrl+T : Toggle paste mode\n\n"); wprintw(win, " (Note: Custom keybindings override these defaults.)\n\n"); help_draw_bottom_menu(win); box(win, ACS_VLINE, ACS_HLINE); wnoutrefresh(win); } static void help_draw_conference(ToxWindow *self) { WINDOW *win = self->help->win; wmove(win, 1, 1); wattron(win, A_BOLD | COLOR_PAIR(RED)); wprintw(win, "Conference commands:\n"); wattroff(win, A_BOLD | COLOR_PAIR(RED)); wprintw(win, " /title : Show/set conference title\n"); #ifdef AUDIO wattron(win, A_BOLD); wprintw(win, "\n Audio:\n"); wattroff(win, A_BOLD); wprintw(win, " /audio or : Enable/disable audio in an audio conference\n"); wprintw(win, " /mute : Toggle self audio mute status\n"); wprintw(win, " /mute or : Toggle peer audio mute status\n"); wprintw(win, " /ptt or : Toggle audio input Push-To-Talk (F2 to activate)\n"); wprintw(win, " /sense : VAD sensitivity threshold\n\n"); #endif help_draw_bottom_menu(win); box(win, ACS_VLINE, ACS_HLINE); wnoutrefresh(win); } #ifdef PYTHON static void help_draw_plugin(ToxWindow *self) { WINDOW *win = self->help->win; wmove(win, 1, 1); wattron(win, A_BOLD | COLOR_PAIR(RED)); wprintw(win, "Plugin commands:\n"); wattroff(win, A_BOLD | COLOR_PAIR(RED)); draw_handler_help(win); help_draw_bottom_menu(win); box(win, ACS_VLINE, ACS_HLINE); wnoutrefresh(win); } #endif /* PYTHON */ static void help_draw_contacts(ToxWindow *self) { WINDOW *win = self->help->win; wmove(win, 1, 1); wattron(win, A_BOLD | COLOR_PAIR(RED)); wprintw(win, "Friendlist controls:\n"); wattroff(win, A_BOLD | COLOR_PAIR(RED)); wprintw(win, " Up and Down arrows : Scroll through list\n"); wprintw(win, " Right and Left arrows : Switch between friendlist and blocked list\n"); wprintw(win, " Enter : Open a chat window with selected contact\n"); wprintw(win, " Delete : Permanently delete a contact\n"); wprintw(win, " B : Block or unblock a contact\n"); help_draw_bottom_menu(win); box(win, ACS_VLINE, ACS_HLINE); wnoutrefresh(win); } void help_onKey(ToxWindow *self, wint_t key) { int height; switch (key) { case L'x': case T_KEY_ESC: help_exit(self); break; case L'c': #ifdef VIDEO help_init_window(self, 26, 80); #elif AUDIO help_init_window(self, 21, 80); #else help_init_window(self, 11, 80); #endif self->help->type = HELP_CHAT; break; case L'g': height = 22; #ifdef VIDEO height += 8; #elif AUDIO height += 4; #endif #ifdef PYTHON height += 2; #endif #ifdef GAMES height += 1; #endif help_init_window(self, height, 80); self->help->type = HELP_GLOBAL; break; case L'o': height = 6; #ifdef AUDIO height += 7; #endif help_init_window(self, height, 80); self->help->type = HELP_CONFERENCE; break; #ifdef PYTHON case L'p': help_init_window(self, 4 + num_registered_handlers(), help_max_width()); self->help->type = HELP_PLUGIN; break; #endif /* PYTHON */ case L'f': help_init_window(self, 10, 80); self->help->type = HELP_CONTACTS; break; case L'k': help_init_window(self, 15, 80); self->help->type = HELP_KEYS; break; case L'm': help_init_menu(self); self->help->type = HELP_MENU; break; case L'r': help_init_window(self, 26, 80); self->help->type = HELP_GROUP; break; } } void help_onDraw(ToxWindow *self) { switch (self->help->type) { case HELP_MENU: help_draw_menu(self); return; case HELP_CHAT: help_draw_chat(self); break; case HELP_GLOBAL: help_draw_global(self); break; case HELP_KEYS: help_draw_keys(self); break; case HELP_CONTACTS: help_draw_contacts(self); break; case HELP_CONFERENCE: help_draw_conference(self); break; #ifdef PYTHON case HELP_PLUGIN: help_draw_plugin(self); break; #endif /* PYTHON */ case HELP_GROUP: help_draw_groupchats(self); break; } }